diff options
author | Lu, Pen-ChunX <pen-chunx.lu@intel.com> | 2024-06-15 00:48:28 +0800 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2024-11-07 10:01:18 +0000 |
commit | f214acd6e570fa053f4a6366d6d4609f10a4ad80 (patch) | |
tree | 86bedd6673a15fead876a12d5a56113b835ef039 /src/soc/intel/xeon_sp | |
parent | a80461f84b0a1fa6f4f41eee8564f6f192b86fc0 (diff) |
soc/intel/xeon_sp: Add acpigen_write_PRT_pre_routed
acpigen_write_PRT_pre_routed writes _PRT covering all direct
subordinate child devices based on interrupt line/pin info from
their PCI configuration spaces. It is required that IRQ routing
and PCI configuration space update to be done ahead of time.
TEST=Build and boot on intel/archercity CRB
Change-Id: Ic54888f76d2ec9804442bec5aec54267d9a16d7c
Signed-off-by: Lu, Pen-ChunX <pen-chunx.lu@intel.com>
Signed-off-by: Shuo Liu <shuo.liu@intel.com>
Signed-off-by: Jincheng Li <jincheng.li@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/82253
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
Diffstat (limited to 'src/soc/intel/xeon_sp')
-rw-r--r-- | src/soc/intel/xeon_sp/acpi.c | 41 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/include/soc/acpi.h | 1 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c index 33db9e65b4..8d74240bd3 100644 --- a/src/soc/intel/xeon_sp/acpi.c +++ b/src/soc/intel/xeon_sp/acpi.c @@ -8,6 +8,7 @@ #include <soc/chip_common.h> #include <soc/pci_devs.h> #include <soc/util.h> +#include <southbridge/intel/common/acpi_pirq_gen.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -193,3 +194,43 @@ void acpigen_write_pci_root_port(const struct device *rp) acpigen_pop_len(); acpigen_pop_len(); } + +void acpigen_write_PRT_pre_routed(const struct device *br) +{ + int dev_num = 0; + uint32_t routed_dev_bitmap = 0; + char *entry_count; + + if (!is_pci_bridge(br)) + return; + + const char *acpi_scope = acpi_device_path(br); + if (!acpi_scope) + return; + + acpigen_write_scope(acpi_scope); + acpigen_write_name("_PRT"); + entry_count = acpigen_write_package(0); + + struct device *dev = NULL; + while ((dev = dev_bus_each_child(br->downstream, dev))) { + if (!is_pci(dev)) + continue; + dev_num = PCI_SLOT(dev->path.pci.devfn); + if (routed_dev_bitmap & (1 << dev_num)) + continue; + + uint8_t int_line = pci_read_config8(dev, PCI_INTERRUPT_LINE); + uint8_t int_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN); + if ((int_pin > PCI_INT_MAX) || (int_pin < PCI_INT_A)) + continue; + + acpigen_write_PRT_GSI_entry(dev_num, int_pin - PCI_INT_A, int_line); + + (*entry_count)++; + routed_dev_bitmap |= (1 << dev_num); + } + + acpigen_pop_len(); + acpigen_pop_len(); +} diff --git a/src/soc/intel/xeon_sp/include/soc/acpi.h b/src/soc/intel/xeon_sp/include/soc/acpi.h index fd693c809d..061814790c 100644 --- a/src/soc/intel/xeon_sp/include/soc/acpi.h +++ b/src/soc/intel/xeon_sp/include/soc/acpi.h @@ -39,5 +39,6 @@ void acpigen_write_OSC_pci_domain_fixed_caps(const struct device *domain, const bool is_cxl_domain, const uint32_t granted_cxl_features); void acpigen_write_pci_root_port(const struct device *rp); +void acpigen_write_PRT_pre_routed(const struct device *br); #endif /* _SOC_ACPI_H_ */ |