Attention is currently required from: Arthur Heymans, Christian Walter, Jincheng Li, Johnny Lin, Jonathan Zhang, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Hello Jincheng Li,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/81569?usp=email
to review the following change.
Change subject: soc/intel/xeon_sp: Add xeonsp_acpigen_write_PRT_pci_bridge ......................................................................
soc/intel/xeon_sp: Add xeonsp_acpigen_write_PRT_pci_bridge
Add support of _PRT SSDT generation for PCI domain and root ports. The routing info is based on PCI interrupt pin/line info configured in pch_pirq_init() ahead of time.
Change-Id: I98497523d11fcdd3724bc6b09585a3fe17fec2a7 Signed-off-by: Shuo Liu shuo.liu@intel.com Signed-off-by: Jincheng Li jincheng.li@intel.com --- M src/soc/intel/xeon_sp/acpi.c M src/soc/intel/xeon_sp/gnr/chip.c M src/soc/intel/xeon_sp/gnr/soc_acpi.c M src/soc/intel/xeon_sp/include/soc/acpi.h 4 files changed, 70 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/69/81569/1
diff --git a/src/soc/intel/xeon_sp/acpi.c b/src/soc/intel/xeon_sp/acpi.c index 9881138..1c2ef76 100644 --- a/src/soc/intel/xeon_sp/acpi.c +++ b/src/soc/intel/xeon_sp/acpi.c @@ -1,10 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <acpi/acpigen.h> +#include <acpi/acpigen_pci.h> #include <assert.h> +#include <device/pci_ops.h> #include <intelblocks/acpi.h> #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 <stdlib.h>
@@ -206,3 +210,43 @@
return NULL; } + +void xeonsp_acpigen_write_PRT_pci_bridge(const struct device *br) +{ + int dev_num = 0; + uint32_t routed_dev_bitmap = 0; + char *entry_count; + + if ((!is_pci_bridge(br)) && (br->path.type != DEVICE_PATH_DOMAIN)) + 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/gnr/chip.c b/src/soc/intel/xeon_sp/gnr/chip.c index c918587..3be2d10 100644 --- a/src/soc/intel/xeon_sp/gnr/chip.c +++ b/src/soc/intel/xeon_sp/gnr/chip.c @@ -3,12 +3,14 @@ #include <arch/hpet.h> #include <arch/ioapic.h> #include <assert.h> +#include <bootstate.h> #include <console/console.h> #include <console/debug.h> #include <cpu/x86/lapic.h> #include <device/pci.h> #include <gpio.h> #include <intelblocks/gpio.h> +#include <intelblocks/itss.h> #include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <intelblocks/pmclib.h> @@ -18,6 +20,7 @@ #include <soc/chip_common.h> #include <soc/cpu.h> #include <soc/pch.h> +#include <soc/pcr_ids.h> #include <soc/ramstage.h> #include <soc/soc_util.h> #include <soc/util.h> @@ -89,3 +92,15 @@ { mainboard_silicon_init_params(silupd); } + +static void pirq_init(void *unused) +{ + /* to program irq pin/line for pci devices */ + pch_pirq_init(); + /* set polarity low for PIRQA to PIRQH */ + for (int i = 0; i < PIRQ_COUNT; i++) { + itss_set_irq_polarity(pcr_read8(PID_ITSS, PCR_ITSS_PIRQA_ROUT + i), 1); + } +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pirq_init, NULL); diff --git a/src/soc/intel/xeon_sp/gnr/soc_acpi.c b/src/soc/intel/xeon_sp/gnr/soc_acpi.c index d8160fc..d960b9e 100644 --- a/src/soc/intel/xeon_sp/gnr/soc_acpi.c +++ b/src/soc/intel/xeon_sp/gnr/soc_acpi.c @@ -109,6 +109,15 @@
acpigen_pop_len(); acpigen_pop_len(); + + /* _PRT */ + xeonsp_acpigen_write_PRT_pci_bridge(domain); + struct device *dev = NULL; + while ((dev = dev_bus_each_child(domain->downstream, dev))) { + if (!is_pci_bridge(dev)) + continue; + xeonsp_acpigen_write_PRT_pci_bridge(dev); + } }
uint32_t soc_get_granted_pci_features(const struct device *domain) diff --git a/src/soc/intel/xeon_sp/include/soc/acpi.h b/src/soc/intel/xeon_sp/include/soc/acpi.h index 7ab681e..6d611db 100644 --- a/src/soc/intel/xeon_sp/include/soc/acpi.h +++ b/src/soc/intel/xeon_sp/include/soc/acpi.h @@ -26,4 +26,6 @@ void iio_domain_set_acpi_name(struct device *dev, const char *prefix); void iio_domain_set_root_port_acpi_names(const struct device *domain);
+void xeonsp_acpigen_write_PRT_pci_bridge(const struct device *br); + #endif /* _SOC_ACPI_H_ */