1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci_def.h>
8 #include <device/pci_ops.h>
9 #include <device/resource.h>
11 #include <intelblocks/acpi.h>
12 #include <intelblocks/irq.h>
15 #include <soc/pci_devs.h>
20 #include "common/fsp_hob.h"
22 static void soc_silicon_init_params(FSPS_UPD
*supd
)
24 const struct microcode
*microcode_file
;
27 microcode_file
= cbfs_map("cpu_microcode_blob.bin", µcode_len
);
28 if (microcode_file
&& (microcode_len
!= 0)) {
29 supd
->FspsConfig
.PcdCpuMicrocodePatchBase
= (UINT32
)microcode_file
;
30 supd
->FspsConfig
.PcdCpuMicrocodePatchSize
= (UINT32
)microcode_len
;
34 /* UPD parameters to be initialized before SiliconInit */
35 void platform_fsp_silicon_init_params_cb(FSPS_UPD
*supd
)
37 soc_silicon_init_params(supd
);
38 mainboard_silicon_init_params(supd
);
41 static void chip_domain_resource_table_init(config_t
*chip_info
)
43 memset(&chip_info
->domain
, 0, sizeof(chip_info
->domain
));
45 * Valid resource range meets base <= limit.
47 for (int i
= 0; i
< MAX_DOMAIN
; i
++) {
48 chip_info
->domain
[i
].bus_base
= UINT8_MAX
;
49 chip_info
->domain
[i
].io_base
= UINT16_MAX
;
50 chip_info
->domain
[i
].mem32_base
= UINT32_MAX
;
51 chip_info
->domain
[i
].mem64_base
= UINT64_MAX
;
55 static void chip_domain_resource_table_load(config_t
*chip_info
)
57 const BL_IIO_UDS
*hob
= fsp_hob_get_iio_uds_data();
59 die("FSP HOB IIO UDS DATA not found!\n");
62 * Assert for `numofIIO` and `BL_MAX_LOGIC_IIO_STACK` so the following loop effects.
64 assert(hob
->PlatformData
.numofIIO
== 1);
65 assert(BL_MAX_LOGIC_IIO_STACK
);
67 const BL_STACK_RES
*stack_res
= hob
->PlatformData
.IIO_resource
[0].StackRes
;
68 for (int i
= 0; i
< BL_MAX_LOGIC_IIO_STACK
; i
++) {
69 struct snr_domain
*domain
= &chip_info
->domain
[i
];
70 domain
->personality
= stack_res
[i
].Personality
;
73 * SNR FSP uses specific enumerations for different type of stacks, see
74 * vendorcode/intel/fsp/fsp2_0/snowridge/FspmUpd.h.
76 if (stack_res
[i
].Personality
>= BL_TYPE_DISABLED
)
79 if (stack_res
[i
].BusBase
> stack_res
[i
].BusLimit
)
80 die("Incorrect bus base 0x%02x and limit 0x%02x for domain %d",
81 stack_res
[i
].BusBase
, stack_res
[i
].BusLimit
, i
);
83 domain
->bus_base
= stack_res
[i
].BusBase
;
84 domain
->bus_limit
= stack_res
[i
].BusLimit
;
87 * Stack with `BL_TYPE_RESERVED` personality has valid bus range but no IO and MMIO resources.
89 if (stack_res
[i
].Personality
== BL_TYPE_RESERVED
)
92 domain
->enabled
= true;
95 * Only non-zero resource base is valid.
97 if (stack_res
[i
].PciResourceIoBase
) {
98 if (stack_res
[i
].PciResourceIoBase
> stack_res
[i
].PciResourceIoLimit
)
99 die("Incorrect IO base 0x%04x and limit 0x%04x for domain %d",
100 stack_res
[i
].PciResourceIoBase
,
101 stack_res
[i
].PciResourceIoLimit
, i
);
103 domain
->io_base
= stack_res
[i
].PciResourceIoBase
;
104 domain
->io_limit
= stack_res
[i
].PciResourceIoLimit
;
107 if (stack_res
[i
].PciResourceMem32Base
) {
108 if (stack_res
[i
].PciResourceMem32Base
>
109 stack_res
[i
].PciResourceMem32Limit
)
110 die("Incorrect Mem32 base 0x%08x and limit 0x%08x for domain %d",
111 stack_res
[i
].PciResourceMem32Base
,
112 stack_res
[i
].PciResourceMem32Limit
, i
);
114 domain
->mem32_base
= stack_res
[i
].PciResourceMem32Base
;
115 domain
->mem32_limit
= stack_res
[i
].PciResourceMem32Limit
;
118 if (stack_res
[i
].PciResourceMem64Base
) {
119 if (stack_res
[i
].PciResourceMem64Base
>
120 stack_res
[i
].PciResourceMem64Limit
)
121 die("Incorrect Mem64 base 0x%16llx and limit 0x%16llx for domain %d",
122 stack_res
[i
].PciResourceMem64Base
,
123 stack_res
[i
].PciResourceMem64Limit
, i
);
125 domain
->mem64_base
= stack_res
[i
].PciResourceMem64Base
;
126 domain
->mem64_limit
= stack_res
[i
].PciResourceMem64Limit
;
131 static void chip_cfg_domain_resource_table_split(config_t
*chip_info
, int base_domain_index
,
132 int addtional_domain_index
)
134 assert(base_domain_index
< MAX_DOMAIN
);
135 assert(addtional_domain_index
< MAX_DOMAIN
);
137 struct snr_domain
*base_domain
= &chip_info
->domain
[base_domain_index
];
138 struct snr_domain
*addtional_domain
= &chip_info
->domain
[addtional_domain_index
];
139 memcpy(addtional_domain
, base_domain
, sizeof(*addtional_domain
));
142 * Base + (Limit - Base) / 2 to avoid overflow.
144 if (base_domain
->bus_base
< base_domain
->bus_limit
) {
145 base_domain
->bus_limit
= base_domain
->bus_base
+
146 (base_domain
->bus_limit
- base_domain
->bus_base
) / 2;
147 addtional_domain
->bus_base
= base_domain
->bus_limit
+ 1;
150 if (base_domain
->io_base
< base_domain
->io_limit
) {
151 base_domain
->io_limit
= base_domain
->io_base
+
152 (base_domain
->io_limit
- base_domain
->io_base
) / 2;
153 addtional_domain
->io_base
= base_domain
->io_limit
+ 1;
156 if (base_domain
->mem32_base
< base_domain
->mem32_limit
) {
157 base_domain
->mem32_limit
=
158 base_domain
->mem32_base
+
159 (base_domain
->mem32_limit
- base_domain
->mem32_base
) / 2;
160 addtional_domain
->mem32_base
= base_domain
->mem32_limit
+ 1;
163 if (base_domain
->mem64_base
< base_domain
->mem64_limit
) {
164 base_domain
->mem64_limit
=
165 base_domain
->mem64_base
+
166 (base_domain
->mem64_limit
- base_domain
->mem64_base
) / 2;
167 addtional_domain
->mem64_base
= base_domain
->mem64_limit
+ 1;
171 static void chip_domain_resource_table_handle_multi_root(config_t
*chip_info
)
174 * Split domains that have more than 1 root bus.
176 int addtional_domain
= BL_MAX_LOGIC_IIO_STACK
;
177 chip_cfg_domain_resource_table_split(chip_info
, 7,
178 addtional_domain
++); /**< Domain 8 (Ubox1). */
180 if (chip_info
->domain
[2].enabled
)
181 chip_cfg_domain_resource_table_split(
183 addtional_domain
++); /**< Domain 2 (S2) has an extra root bus for Intel DLB. */
186 static void chip_domain_resource_table_dump(config_t
*chip_info
)
189 "---------------------------------------------------------------------------------------------------------------------\n"
190 "| Domain | Enabled | Bus Base/Limit | IO Base/Limit | Mem32 Base/Limit | Mem64 Base/Limit |\n"
191 "---------------------------------------------------------------------------------------------------------------------\n");
192 for (int i
= 0; i
< MAX_DOMAIN
; i
++) {
193 struct snr_domain
*domain
= &chip_info
->domain
[i
];
195 "| %2u | %c(0x%02x) | 0x%02x/0x%02x | 0x%04x/0x%04x | 0x%08x/0x%08x | 0x%016llx/0x%016llx |\n",
196 i
, domain
->enabled
? 'Y' : 'N', domain
->personality
, domain
->bus_base
,
197 domain
->bus_limit
, domain
->io_base
, domain
->io_limit
, domain
->mem32_base
,
198 domain
->mem32_limit
, domain
->mem64_base
, domain
->mem64_limit
);
201 "---------------------------------------------------------------------------------------------------------------------\n");
204 static void chip_domain_resource_table_fill(config_t
*chip_info
)
206 chip_domain_resource_table_init(chip_info
);
207 chip_domain_resource_table_load(chip_info
);
208 chip_domain_resource_table_handle_multi_root(chip_info
);
209 chip_domain_resource_table_dump(chip_info
);
212 static void devicetree_domain_definition_update(config_t
*chip_info
)
214 struct device
*dev
= NULL
;
218 * Check static domain id agaginst dynamic and fill domain device.
220 while ((dev
= dev_find_path(dev
, DEVICE_PATH_DOMAIN
)) != NULL
) {
221 domain
= dev_get_domain_id(dev
);
222 if (domain
>= MAX_DOMAIN
)
223 die("Incorrect domain[%d] in devicetree\n", domain
);
225 chip_info
->domain
[domain
].dev
= dev
;
227 printk(BIOS_SPEW
, "%s -> domain[%d] defined in devicetree\n", dev_path(dev
),
231 if (!chip_info
->domain
[0].dev
)
232 die("Please add domain 0 to device tree!\n");
234 for (domain
= 0; domain
< MAX_DOMAIN
; domain
++) {
235 if (!chip_info
->domain
[domain
].enabled
) {
236 if (chip_info
->domain
[domain
].dev
&&
237 chip_info
->domain
[domain
].dev
->enabled
) {
239 "Domain[%d] is disabled, reserved or not existed but defined in device tree!\n",
241 dev_set_enabled(chip_info
->domain
[domain
].dev
, false);
246 if (!chip_info
->domain
[domain
].dev
)
247 die("Domain[%d] is enabled but not defined in device tree!\n", domain
);
249 dev
= chip_info
->domain
[domain
].dev
;
251 printk(BIOS_SPEW
, "Domain[%d] is enabled, updating PCI root bus to 0x%02x\n",
252 domain
, chip_info
->domain
[domain
].bus_base
);
254 /* Use same bus number for secondary and subordinate before PCI enumeration. */
255 dev
->downstream
->secondary
= dev
->downstream
->subordinate
=
256 chip_info
->domain
[domain
].bus_base
;
257 dev
->downstream
->max_subordinate
= chip_info
->domain
[domain
].bus_limit
;
261 static void soc_init_pre_device(void *chip_info
)
265 chip_domain_resource_table_fill((config_t
*)chip_info
);
267 devicetree_domain_definition_update((config_t
*)chip_info
);
270 static void domain_read_resources(struct device
*dev
)
272 struct resource
*res
;
274 const uint8_t domain
= dev
->path
.domain
.domain_id
;
275 const config_t
*chip_info
= dev
->chip_info
;
277 printk(BIOS_DEBUG
, "Reading resources for %s\n", dev_path(dev
));
280 * Allocate IO resource.
282 if (chip_info
->domain
[domain
].io_limit
>= chip_info
->domain
[domain
].io_base
) {
283 res
= new_resource(dev
, index
++);
285 die("Allocate resource for %s failed!\n", dev_path(dev
));
287 res
->base
= chip_info
->domain
[domain
].io_base
;
288 res
->limit
= chip_info
->domain
[domain
].io_limit
;
289 res
->size
= res
->limit
- res
->base
+ 1;
290 res
->flags
= IORESOURCE_IO
| IORESOURCE_ASSIGNED
;
291 printk(BIOS_SPEW
, "IO Base/Limit: 0x%04llx/0x%04llx\n", res
->base
, res
->limit
);
295 * Allocate Mem32 resource.
297 if (chip_info
->domain
[domain
].mem32_limit
>= chip_info
->domain
[domain
].mem32_base
) {
298 res
= new_resource(dev
, index
++);
300 die("Allocate resource for %s failed!\n", dev_path(dev
));
302 res
->base
= chip_info
->domain
[domain
].mem32_base
;
303 res
->limit
= chip_info
->domain
[domain
].mem32_limit
;
304 res
->size
= res
->limit
- res
->base
+ 1;
305 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
;
306 printk(BIOS_SPEW
, "Mem32 Base/Limit: 0x%08llx/0x%08llx\n", res
->base
,
311 * Allocate Mem64 resource.
313 if (chip_info
->domain
[domain
].mem64_limit
>= chip_info
->domain
[domain
].mem64_base
) {
314 res
= new_resource(dev
, index
++);
316 die("Allocate resource for %s failed!\n", dev_path(dev
));
318 res
->base
= chip_info
->domain
[domain
].mem64_base
;
319 res
->limit
= chip_info
->domain
[domain
].mem64_limit
;
320 res
->size
= res
->limit
- res
->base
+ 1;
321 res
->flags
= IORESOURCE_MEM
| IORESOURCE_ASSIGNED
| IORESOURCE_PCI64
|
323 printk(BIOS_SPEW
, "Mem64 Base/Limit: 0x%016llx/0x%016llx\n", res
->base
,
327 printk(BIOS_DEBUG
, "Reading resources for %s done\n", dev_path(dev
));
330 static void domain_set_resources(struct device
*dev
)
332 printk(BIOS_DEBUG
, "Setting resources for %s\n", dev_path(dev
));
334 pci_domain_set_resources(dev
);
336 printk(BIOS_DEBUG
, "Setting resources for %s done\n", dev_path(dev
));
339 static void domain_scan_bus(struct device
*dev
)
341 printk(BIOS_DEBUG
, "Scanning %s\n", dev_path(dev
));
343 pci_host_bridge_scan_bus(dev
);
345 printk(BIOS_DEBUG
, "Scanning %s done\n", dev_path(dev
));
348 const char *soc_acpi_name(const struct device
*dev
)
350 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
)
351 switch (dev_get_domain_id(dev
)) {
379 static struct device_operations pci_domain_ops
= {
380 .read_resources
= domain_read_resources
,
381 .set_resources
= domain_set_resources
,
382 .scan_bus
= domain_scan_bus
,
383 .acpi_fill_ssdt
= domain_fill_ssdt
,
384 .acpi_name
= soc_acpi_name
,
387 static struct device_operations cpu_bus_ops
= {
388 .read_resources
= noop_read_resources
,
389 .set_resources
= noop_set_resources
,
390 .acpi_fill_ssdt
= generate_cpu_entries
,
393 static void southcluster_enable_dev(struct device
*dev
)
396 printk(BIOS_DEBUG
, "Disable %s\n", dev_path(dev
));
398 * Mark the device as hidden so that coreboot won't complain about leftover static
402 pci_and_config16(dev
, PCI_COMMAND
,
403 ~(PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER
));
405 printk(BIOS_DEBUG
, "Enable %s\n", dev_path(dev
));
406 pci_or_config16(dev
, PCI_COMMAND
, PCI_COMMAND_SERR
);
410 static void soc_enable_dev(struct device
*dev
)
412 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
) {
413 printk(BIOS_SPEW
, "Set domain operation for %s\n", dev_path(dev
));
414 dev
->ops
= &pci_domain_ops
;
415 } else if (dev
->path
.type
== DEVICE_PATH_CPU_CLUSTER
) {
416 printk(BIOS_SPEW
, "Set CPU cluster operation for %s\n", dev_path(dev
));
417 dev
->ops
= &cpu_bus_ops
;
418 } else if (dev
->path
.type
== DEVICE_PATH_PCI
) {
420 * For a static PCH device, if it's enabled, set the SERR bits, otherwise
421 * disable the ability of issuing and responding to IO and memory requests.
423 if (is_dev_on_domain0(dev
) && is_pci(dev
) && is_pch_slot(dev
->path
.pci
.devfn
))
424 southcluster_enable_dev(dev
);
428 struct chip_operations soc_intel_snowridge_ops
= {
429 .name
= "Intel Snowridge",
430 .init
= &soc_init_pre_device
,
431 .enable_dev
= &soc_enable_dev
,