coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pci_ops.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef PCI_OPS_H
4 #define PCI_OPS_H
5 
6 #include <stdint.h>
7 #include <device/device.h>
8 #include <device/pci_type.h>
9 #include <arch/pci_ops.h>
10 
11 void __noreturn pcidev_die(void);
12 
13 static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev)
14 {
15  return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20);
16 }
17 
19 {
20  if (!dev)
21  pcidev_die();
22  return pcidev_bdf(dev);
23 }
24 
25 #if defined(__SIMPLE_DEVICE__)
26 #define ENV_PCI_SIMPLE_DEVICE 1
27 #else
28 #define ENV_PCI_SIMPLE_DEVICE 0
29 #endif
30 
31 #if ENV_PCI_SIMPLE_DEVICE
32 
33 /* Avoid name collisions as different stages have different signature
34  * for these functions. The _s_ stands for simple, fundamental IO or
35  * MMIO variant.
36  */
37 #define pci_read_config8 pci_s_read_config8
38 #define pci_read_config16 pci_s_read_config16
39 #define pci_read_config32 pci_s_read_config32
40 #define pci_write_config8 pci_s_write_config8
41 #define pci_write_config16 pci_s_write_config16
42 #define pci_write_config32 pci_s_write_config32
43 #else
44 
45 static __always_inline
46 u8 pci_read_config8(const struct device *dev, u16 reg)
47 {
48  return pci_s_read_config8(PCI_BDF(dev), reg);
49 }
50 
51 static __always_inline
52 u16 pci_read_config16(const struct device *dev, u16 reg)
53 {
54  return pci_s_read_config16(PCI_BDF(dev), reg);
55 }
56 
57 static __always_inline
58 u32 pci_read_config32(const struct device *dev, u16 reg)
59 {
60  return pci_s_read_config32(PCI_BDF(dev), reg);
61 }
62 
63 static __always_inline
64 void pci_write_config8(const struct device *dev, u16 reg, u8 val)
65 {
66  pci_s_write_config8(PCI_BDF(dev), reg, val);
67 }
68 
69 static __always_inline
70 void pci_write_config16(const struct device *dev, u16 reg, u16 val)
71 {
72  pci_s_write_config16(PCI_BDF(dev), reg, val);
73 }
74 
75 static __always_inline
76 void pci_write_config32(const struct device *dev, u16 reg, u32 val)
77 {
78  pci_s_write_config32(PCI_BDF(dev), reg, val);
79 }
80 
81 #endif
82 
83 #if ENV_PCI_SIMPLE_DEVICE
84 static __always_inline
85 void pci_update_config8(pci_devfn_t dev, u16 reg, u8 mask, u8 or)
86 #else
87 static __always_inline
88 void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
89 #endif
90 {
91  u8 reg8;
92 
93  reg8 = pci_read_config8(dev, reg);
94  reg8 &= mask;
95  reg8 |= or;
96  pci_write_config8(dev, reg, reg8);
97 }
98 
99 #if ENV_PCI_SIMPLE_DEVICE
100 static __always_inline
101 void pci_update_config16(pci_devfn_t dev, u16 reg, u16 mask, u16 or)
102 #else
103 static __always_inline
104 void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
105 #endif
106 {
107  u16 reg16;
108 
109  reg16 = pci_read_config16(dev, reg);
110  reg16 &= mask;
111  reg16 |= or;
112  pci_write_config16(dev, reg, reg16);
113 }
114 
115 #if ENV_PCI_SIMPLE_DEVICE
116 static __always_inline
117 void pci_update_config32(pci_devfn_t dev, u16 reg, u32 mask, u32 or)
118 #else
119 static __always_inline
120 void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
121 #endif
122 {
123  u32 reg32;
124 
125  reg32 = pci_read_config32(dev, reg);
126  reg32 &= mask;
127  reg32 |= or;
128  pci_write_config32(dev, reg, reg32);
129 }
130 
131 #if ENV_PCI_SIMPLE_DEVICE
132 static __always_inline
133 void pci_and_config8(pci_devfn_t dev, u16 reg, u8 andmask)
134 #else
135 static __always_inline
136 void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
137 #endif
138 {
139  pci_update_config8(dev, reg, andmask, 0);
140 }
141 
142 #if ENV_PCI_SIMPLE_DEVICE
143 static __always_inline
144 void pci_and_config16(pci_devfn_t dev, u16 reg, u16 andmask)
145 #else
146 static __always_inline
147 void pci_and_config16(const struct device *dev, u16 reg, u16 andmask)
148 #endif
149 {
150  pci_update_config16(dev, reg, andmask, 0);
151 }
152 
153 #if ENV_PCI_SIMPLE_DEVICE
154 static __always_inline
155 void pci_and_config32(pci_devfn_t dev, u16 reg, u32 andmask)
156 #else
157 static __always_inline
158 void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
159 #endif
160 {
161  pci_update_config32(dev, reg, andmask, 0);
162 }
163 
164 #if ENV_PCI_SIMPLE_DEVICE
165 static __always_inline
166 void pci_or_config8(pci_devfn_t dev, u16 reg, u8 ormask)
167 #else
168 static __always_inline
169 void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
170 #endif
171 {
172  pci_update_config8(dev, reg, 0xff, ormask);
173 }
174 
175 #if ENV_PCI_SIMPLE_DEVICE
176 static __always_inline
177 void pci_or_config16(pci_devfn_t dev, u16 reg, u16 ormask)
178 #else
179 static __always_inline
180 void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
181 #endif
182 {
183  pci_update_config16(dev, reg, 0xffff, ormask);
184 }
185 
186 #if ENV_PCI_SIMPLE_DEVICE
187 static __always_inline
188 void pci_or_config32(pci_devfn_t dev, u16 reg, u32 ormask)
189 #else
190 static __always_inline
191 void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
192 #endif
193 {
194  pci_update_config32(dev, reg, 0xffffffff, ormask);
195 }
196 
199 
200 static __always_inline
201 u16 pci_find_next_capability(const struct device *dev, u16 cap, u16 last)
202 {
203  return pci_s_find_next_capability(PCI_BDF(dev), cap, last);
204 }
205 
206 static __always_inline
207 u16 pci_find_capability(const struct device *dev, u16 cap)
208 {
209  return pci_s_find_capability(PCI_BDF(dev), cap);
210 }
211 
212 /*
213  * Determine if the given PCI device is the source of wake from sleep by checking PME_STATUS and
214  * PME_ENABLE bits in PM control and status register.
215  *
216  * Returns true if PCI device is wake source, false otherwise.
217  */
219 
220 #endif /* PCI_OPS_H */
#define __noreturn
Definition: compiler.h:31
#define __always_inline
Definition: compiler.h:35
static __always_inline void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Definition: pci_ops.h:191
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u16 pci_find_next_capability(const struct device *dev, u16 cap, u16 last)
Definition: pci_ops.h:201
static __always_inline void pci_and_config16(const struct device *dev, u16 reg, u16 andmask)
Definition: pci_ops.h:147
u16 pci_s_find_next_capability(pci_devfn_t dev, u16 cap, u16 last)
Given a device, a capability type, and a last position, return the next matching capability.
Definition: pci_ops.c:21
static __always_inline void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
Definition: pci_ops.h:136
static __always_inline void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Definition: pci_ops.h:120
static __always_inline void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Definition: pci_ops.h:88
static __always_inline pci_devfn_t pcidev_assert(const struct device *dev)
Definition: pci_ops.h:18
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
Definition: pci_ops.h:169
u16 pci_s_find_capability(pci_devfn_t dev, u16 cap)
Given a device, and a capability type, return the next matching capability.
Definition: pci_ops.c:72
static __always_inline u16 pci_find_capability(const struct device *dev, u16 cap)
Definition: pci_ops.h:207
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev)
Definition: pci_ops.h:13
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Definition: pci_ops.h:104
void __noreturn pcidev_die(void)
Definition: pci_ops.c:77
bool pci_dev_is_wake_source(pci_devfn_t dev)
Definition: pci_ops.c:82
static __always_inline void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
Definition: pci_ops.h:158
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
static __always_inline uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:92
static __always_inline uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:86
static __always_inline uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:80
static __always_inline void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
Definition: pci_io_cfg.h:98
static __always_inline void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
Definition: pci_io_cfg.h:104
static __always_inline void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
Definition: pci_io_cfg.h:110
#define PCI_BDF(dev)
Definition: pci_type.h:28
u32 pci_devfn_t
Definition: pci_type.h:8
static const int mask[4]
Definition: gpio.c:308
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
uint16_t secondary
Definition: device.h:84
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST struct bus * bus
Definition: device.h:108
unsigned int devfn
Definition: path.h:54
u8 val
Definition: sys.c:300