xref: /aosp_15_r20/external/coreboot/src/cpu/x86/smm/pci_resource_store.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cpu/x86/smm.h>
4 #include <device/device.h>
5 #include <device/pci_def.h>
6 #include <device/pci_ops.h>
7 
smm_pci_get_stored_resources(const volatile struct smm_pci_resource_info ** out_slots,size_t * out_size)8 void smm_pci_get_stored_resources(const volatile struct smm_pci_resource_info **out_slots,
9 				  size_t *out_size)
10 {
11 	*out_slots = smm_get_pci_resource_store();
12 	*out_size = CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS;
13 }
14 
smm_pci_resource_store_fill_resources(struct smm_pci_resource_info * slots,size_t num_slots,const struct device ** devices,size_t num_devices)15 bool smm_pci_resource_store_fill_resources(struct smm_pci_resource_info *slots, size_t num_slots,
16 					   const struct device **devices, size_t num_devices)
17 {
18 	size_t i_slot = 0;
19 
20 	for (size_t i_dev = 0; i_dev < num_devices; i_dev++) {
21 		if (i_slot >= num_slots) {
22 			printk(BIOS_ERR, "Failed to store all PCI resources, number of devices exceeds %zd slots\n",
23 			       num_slots);
24 			return false;
25 		}
26 
27 		if (!is_pci(devices[i_dev])) {
28 			printk(BIOS_WARNING, "Skipping storing PCI resources for device at index %zd, not a PCI device\n",
29 			       i_dev);
30 			continue;
31 		}
32 
33 		pci_devfn_t pci_addr = PCI_BDF(devices[i_dev]);
34 		slots[i_slot].pci_addr = pci_addr;
35 		slots[i_slot].class_device = PCI_CLASS_GET_DEVICE(devices[i_dev]->class);
36 		slots[i_slot].class_prog = PCI_CLASS_GET_PROG(devices[i_dev]->class);
37 		slots[i_slot].vendor_id = devices[i_dev]->vendor;
38 		slots[i_slot].device_id = devices[i_dev]->device;
39 
40 		size_t i_res = 0;
41 		for (const struct resource *res = devices[i_dev]->resource_list; res != NULL;
42 			res = res->next) {
43 			slots[i_slot].resources[i_res] = *res;
44 			slots[i_slot].resources[i_res].next = NULL;
45 
46 			if (i_res > 0)
47 				slots[i_slot].resources[i_res - 1].next = (struct resource *)&slots[i_slot].resources[i_res];
48 
49 			if (++i_res >= SMM_PCI_RESOURCE_STORE_NUM_RESOURCES) {
50 				if (res->next)
51 					printk(BIOS_WARNING, "Number of PCI resources exceeds supported storage count\n");
52 				break;
53 			}
54 		}
55 
56 		i_slot++;
57 	}
58 
59 	return true;
60 }
61 
smm_mainboard_pci_resource_store_init(struct smm_pci_resource_info * slots,size_t size)62 void __weak smm_mainboard_pci_resource_store_init(struct smm_pci_resource_info *slots,
63 						  size_t size)
64 {
65 }
66 
smm_pci_resource_store_init(struct smm_runtime * smm_runtime)67 void smm_pci_resource_store_init(struct smm_runtime *smm_runtime)
68 {
69 	smm_mainboard_pci_resource_store_init(&smm_runtime->pci_resources[0],
70 					 CONFIG_SMM_PCI_RESOURCE_STORE_NUM_SLOTS);
71 }
72