1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <console/console.h>
6 #include <device/pci.h>
7 #include <soc/chip_common.h>
8 #include <soc/soc_util.h>
12 static const STACK_RES
*domain_to_stack_res(const struct device
*dev
)
14 assert(dev
->path
.type
== DEVICE_PATH_DOMAIN
);
15 const union xeon_domain_path dn
= {
16 .domain_path
= dev
->path
.domain
.domain
19 const IIO_UDS
*hob
= get_iio_uds();
22 return &hob
->PlatformData
.IIO_resource
[dn
.socket
].StackRes
[dn
.stack
];
25 void iio_pci_domain_read_resources(struct device
*dev
)
28 const STACK_RES
*sr
= domain_to_stack_res(dev
);
35 if (dev
->path
.domain
.domain
== 0) {
36 /* The 0 - 0xfff IO range is not reported by the HOB but still gets decoded */
37 res
= new_resource(dev
, index
++);
41 res
->flags
= IORESOURCE_IO
| IORESOURCE_SUBTRACTIVE
| IORESOURCE_ASSIGNED
;
44 if (sr
->PciResourceIoBase
< sr
->PciResourceIoLimit
) {
45 res
= new_resource(dev
, index
++);
46 res
->base
= sr
->PciResourceIoBase
;
47 res
->limit
= sr
->PciResourceIoLimit
;
48 res
->size
= res
->limit
- res
->base
+ 1;
49 res
->flags
= IORESOURCE_IO
| IORESOURCE_ASSIGNED
;
52 if (sr
->PciResourceMem32Base
< sr
->PciResourceMem32Limit
) {
53 res
= new_resource(dev
, index
++);
54 res
->base
= sr
->PciResourceMem32Base
;
55 res
->limit
= sr
->PciResourceMem32Limit
;
56 res
->size
= res
->limit
- res
->base
+ 1;
57 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
;
60 if (sr
->PciResourceMem64Base
< sr
->PciResourceMem64Limit
) {
61 res
= new_resource(dev
, index
++);
62 res
->base
= sr
->PciResourceMem64Base
;
63 res
->limit
= sr
->PciResourceMem64Limit
;
64 res
->size
= res
->limit
- res
->base
+ 1;
65 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
;
69 void iio_pci_domain_scan_bus(struct device
*dev
)
71 const STACK_RES
*sr
= domain_to_stack_res(dev
);
75 if (!dev
->link_list
) {
76 dev
->link_list
= calloc(1, sizeof(struct bus
));
78 die("%s: out of memory.\n", __func__
);
81 struct bus
*bus
= dev
->link_list
;
83 bus
->secondary
= sr
->BusBase
;
84 bus
->subordinate
= sr
->BusBase
;
85 bus
->max_subordinate
= sr
->BusLimit
;
87 printk(BIOS_SPEW
, "Scanning IIO stack %d: busses %x-%x\n", dev
->path
.domain
.domain
,
88 dev
->link_list
->secondary
, dev
->link_list
->max_subordinate
);
89 pci_host_bridge_scan_bus(dev
);
93 * Used by IIO stacks for PCIe bridges. Those contain 1 PCI host bridges,
94 * all the bus numbers on the IIO stack can be used for this bridge
96 static struct device_operations iio_pcie_domain_ops
= {
97 .read_resources
= iio_pci_domain_read_resources
,
98 .set_resources
= pci_domain_set_resources
,
99 .scan_bus
= iio_pci_domain_scan_bus
,
102 /* Attach IIO stack as domains */
103 void attach_iio_stacks(struct device
*dev
)
105 const IIO_UDS
*hob
= get_iio_uds();
106 union xeon_domain_path dn
= { .domain_path
= 0 };
110 for (int s
= 0; s
< hob
->PlatformData
.numofIIO
; ++s
) {
111 for (int x
= 0; x
< MAX_LOGIC_IIO_STACK
; ++x
) {
112 if (s
== 0 && x
== 0)
115 const STACK_RES
*ri
= &hob
->PlatformData
.IIO_resource
[s
].StackRes
[x
];
116 if (ri
->BusBase
> ri
->BusLimit
)
119 /* Prepare domain path */
122 dn
.bus
= ri
->BusBase
;
124 if (!is_pcie_iio_stack_res(ri
)) {
125 if (CONFIG(HAVE_IOAT_DOMAINS
))
126 soc_create_ioat_domains(dn
, dev
->bus
, ri
);
130 struct device_path path
;
131 path
.type
= DEVICE_PATH_DOMAIN
;
132 path
.domain
.domain
= dn
.domain_path
;
133 struct device
*iio_domain
= alloc_dev(dev
->bus
, &path
);
134 if (iio_domain
== NULL
)
135 die("%s: out of memory.\n", __func__
);
136 iio_domain
->ops
= &iio_pcie_domain_ops
;