1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci_def.h>
7 #include <device/pci_type.h>
11 /** Linked list of ALL devices */
12 DEVTREE_CONST
struct device
*DEVTREE_CONST all_devices
= &dev_root
;
15 * Given a PCI bus and a devfn number, find the device structure.
17 * Note that this function can return the incorrect device prior
18 * to PCI enumeration because the secondary field of the bus object
19 * is 0. The failing scenario is determined by the order of the
20 * devices in all_devices singly-linked list as well as the time
21 * when this function is called (secondary reflecting topology).
23 * @param bus The bus number.
24 * @param devfn A device/function number.
25 * @return Pointer to the device structure (if found), 0 otherwise.
28 static DEVTREE_CONST
struct device
*dev_find_slot(unsigned int bus
,
31 DEVTREE_CONST
struct device
*dev
, *result
;
34 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
35 if ((dev
->path
.type
== DEVICE_PATH_PCI
) &&
36 (dev
->upstream
->secondary
== bus
) &&
37 (dev
->upstream
->segment_group
== 0) &&
38 (dev
->path
.pci
.devfn
== devfn
)) {
47 * Given a Device Path Type, find the device structure.
49 * @param prev_match The previously matched device instance.
50 * @param path_type The Device Path Type.
51 * @return Pointer to the device structure (if found), 0 otherwise.
53 DEVTREE_CONST
struct device
*dev_find_path(
54 DEVTREE_CONST
struct device
*prev_match
,
55 enum device_path_type path_type
)
57 DEVTREE_CONST
struct device
*dev
, *result
= NULL
;
59 if (prev_match
== NULL
)
60 prev_match
= all_devices
;
62 prev_match
= prev_match
->next
;
64 for (dev
= prev_match
; dev
; dev
= dev
->next
) {
65 if (dev
->path
.type
== path_type
) {
74 * Given a device pointer, find the next PCI device.
76 * @param previous_dev A pointer to a PCI device structure.
77 * @return Pointer to the next device structure (if found), 0 otherwise.
79 DEVTREE_CONST
struct device
*dev_find_next_pci_device(
80 DEVTREE_CONST
struct device
*previous_dev
)
82 return dev_find_path(previous_dev
, DEVICE_PATH_PCI
);
85 static int path_eq(const struct device_path
*path1
,
86 const struct device_path
*path2
)
90 if (!path1
|| !path2
) {
93 /* Return 0 in case assert is considered non-fatal. */
97 if (path1
->type
!= path2
->type
)
100 switch (path1
->type
) {
101 case DEVICE_PATH_NONE
:
103 case DEVICE_PATH_ROOT
:
106 case DEVICE_PATH_PCI
:
107 equal
= (path1
->pci
.devfn
== path2
->pci
.devfn
);
109 case DEVICE_PATH_PNP
:
110 equal
= (path1
->pnp
.port
== path2
->pnp
.port
) &&
111 (path1
->pnp
.device
== path2
->pnp
.device
);
113 case DEVICE_PATH_I2C
:
114 equal
= (path1
->i2c
.device
== path2
->i2c
.device
) &&
115 (path1
->i2c
.mode_10bit
== path2
->i2c
.mode_10bit
);
117 case DEVICE_PATH_APIC
:
118 equal
= (path1
->apic
.apic_id
== path2
->apic
.apic_id
);
120 case DEVICE_PATH_DOMAIN
:
121 equal
= (path1
->domain
.domain
== path2
->domain
.domain
);
123 case DEVICE_PATH_CPU_CLUSTER
:
124 equal
= (path1
->cpu_cluster
.cluster
125 == path2
->cpu_cluster
.cluster
);
127 case DEVICE_PATH_CPU
:
128 equal
= (path1
->cpu
.id
== path2
->cpu
.id
);
130 case DEVICE_PATH_CPU_BUS
:
131 equal
= (path1
->cpu_bus
.id
== path2
->cpu_bus
.id
);
133 case DEVICE_PATH_GENERIC
:
134 equal
= (path1
->generic
.id
== path2
->generic
.id
) &&
135 (path1
->generic
.subid
== path2
->generic
.subid
);
137 case DEVICE_PATH_SPI
:
138 equal
= (path1
->spi
.cs
== path2
->spi
.cs
);
140 case DEVICE_PATH_USB
:
141 equal
= (path1
->usb
.port_type
== path2
->usb
.port_type
) &&
142 (path1
->usb
.port_id
== path2
->usb
.port_id
);
144 case DEVICE_PATH_MMIO
:
145 equal
= (path1
->mmio
.addr
== path2
->mmio
.addr
);
147 case DEVICE_PATH_GPIO
:
148 equal
= (path1
->gpio
.id
== path2
->gpio
.id
);
150 case DEVICE_PATH_MDIO
:
151 equal
= (path1
->mdio
.addr
== path2
->mdio
.addr
);
155 printk(BIOS_ERR
, "Unknown device type: %d\n", path1
->type
);
163 * See if a device structure exists for path.
165 * @param parent The bus to find the device on.
166 * @param path The relative path from the bus to the appropriate device.
167 * @return Pointer to a device structure for the device on bus at path
168 * or 0/NULL if no device is found.
170 DEVTREE_CONST
struct device
*find_dev_path(
171 const struct bus
*parent
, const struct device_path
*path
)
173 DEVTREE_CONST
struct device
*child
;
177 /* Return NULL in case asserts are considered non-fatal. */
181 for (child
= parent
->children
; child
; child
= child
->sibling
) {
182 if (path_eq(path
, &child
->path
))
189 * Find the device structure given an array of nested device paths,
191 * @param parent The parent bus to start the search on.
192 * @param nested_path An array of relative paths from the parent bus to the target device.
193 * @param nested_path_length Number of path elements in nested_path array.
194 * @return Pointer to a device structure for the device at nested path
195 * or 0/NULL if no device is found.
197 DEVTREE_CONST
struct device
*find_dev_nested_path(
198 const struct bus
*parent
, const struct device_path nested_path
[],
199 size_t nested_path_length
)
201 DEVTREE_CONST
struct device
*child
;
203 if (!parent
|| !nested_path
|| !nested_path_length
)
206 child
= find_dev_path(parent
, nested_path
);
208 /* Terminate recursion at end of nested path or child not found */
209 if (nested_path_length
== 1 || !child
)
212 return find_dev_nested_path(child
->downstream
, nested_path
+ 1, nested_path_length
- 1);
215 DEVTREE_CONST
struct device
*pcidev_path_behind(
216 const struct bus
*parent
, pci_devfn_t devfn
)
218 const struct device_path path
= {
219 .type
= DEVICE_PATH_PCI
,
222 return find_dev_path(parent
, &path
);
225 DEVTREE_CONST
struct device
*pcidev_path_on_bus(unsigned int bus
, pci_devfn_t devfn
)
227 DEVTREE_CONST
struct bus
*parent
= pci_root_bus();
228 DEVTREE_CONST
struct device
*dev
= parent
->children
;
230 /* FIXME: Write the loop with topology links. */
232 if (dev
->path
.type
!= DEVICE_PATH_PCI
) {
236 if (dev
->upstream
->secondary
== bus
&& dev
->upstream
->segment_group
== 0)
237 return pcidev_path_behind(dev
->upstream
, devfn
);
243 DEVTREE_CONST
struct bus
*pci_root_bus(void)
245 DEVTREE_CONST
struct device
*pci_domain
;
246 static DEVTREE_CONST
struct bus
*pci_root
;
251 pci_domain
= dev_find_path(NULL
, DEVICE_PATH_DOMAIN
);
255 pci_root
= pci_domain
->downstream
;
259 DEVTREE_CONST
struct device
*pcidev_path_on_root(pci_devfn_t devfn
)
261 return pcidev_path_behind(pci_root_bus(), devfn
);
264 DEVTREE_CONST
struct device
*pcidev_on_root(uint8_t dev
, uint8_t fn
)
266 return pcidev_path_on_root(PCI_DEVFN(dev
, fn
));
269 DEVTREE_CONST
struct device
*pcidev_path_behind_pci2pci_bridge(
270 const struct device
*bridge
,
273 if (!bridge
|| (bridge
->path
.type
!= DEVICE_PATH_PCI
)) {
275 /* Return NULL in case asserts are non-fatal. */
279 return pcidev_path_behind(bridge
->downstream
, devfn
);
282 DEVTREE_CONST
struct device
*pcidev_path_on_root_debug(pci_devfn_t devfn
, const char *func
)
284 DEVTREE_CONST
struct device
*dev
= pcidev_path_on_root(devfn
);
288 devtree_bug(func
, devfn
);
290 /* FIXME: This can return wrong device. */
291 return dev_find_slot(0, devfn
);
294 void devtree_bug(const char *func
, pci_devfn_t devfn
)
296 printk(BIOS_ERR
, "BUG: %s requests hidden 00:%02x.%u\n", func
, devfn
>> 3, devfn
& 7);
299 void __noreturn
devtree_die(void)
301 die("DEVTREE: dev or chip_info is NULL\n");
305 * Given an SMBus bus and a device number, find the device structure.
307 * @param bus The bus number.
308 * @param addr A device number.
309 * @return Pointer to the device structure (if found), 0 otherwise.
311 DEVTREE_CONST
struct device
*dev_find_slot_on_smbus(unsigned int bus
,
314 DEVTREE_CONST
struct device
*dev
, *result
;
317 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
318 if ((dev
->path
.type
== DEVICE_PATH_I2C
) &&
319 (dev
->upstream
->secondary
== bus
) &&
320 (dev
->path
.i2c
.device
== addr
)) {
329 * Given a PnP port and a device number, find the device structure.
331 * @param port The I/O port.
332 * @param device Logical device number.
333 * @return Pointer to the device structure (if found), 0 otherwise.
335 DEVTREE_CONST
struct device
*dev_find_slot_pnp(u16 port
, u16 device
)
337 DEVTREE_CONST
struct device
*dev
;
339 for (dev
= all_devices
; dev
; dev
= dev
->next
) {
340 if ((dev
->path
.type
== DEVICE_PATH_PNP
) &&
341 (dev
->path
.pnp
.port
== port
) &&
342 (dev
->path
.pnp
.device
== device
)) {
350 * Given a device and previous match iterate through all the children.
352 * @param bus parent device's bus holding all the children
353 * @param prev_child previous child already traversed, if NULL start at
354 * children of parent bus.
355 * @return pointer to child or NULL when no more children
357 DEVTREE_CONST
struct device
*dev_bus_each_child(const struct bus
*parent
,
358 DEVTREE_CONST
struct device
*prev_child
)
360 DEVTREE_CONST
struct device
*dev
;
365 if (prev_child
== NULL
)
366 dev
= parent
->children
;
368 dev
= prev_child
->sibling
;
373 bool is_dev_enabled(const struct device
*dev
)
378 /* For stages with immutable device tree, first check if device is disabled because of
379 fw_config probing. In these stages, dev->enabled does not reflect the true state of a
380 device that uses fw_config probing. */
381 if (DEVTREE_EARLY
&& !fw_config_probe_dev(dev
, NULL
))
386 bool is_devfn_enabled(unsigned int devfn
)
388 const struct device
*dev
= pcidev_path_on_root(devfn
);
389 return is_dev_enabled(dev
);