diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2022-10-26 00:59:13 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-11-15 14:29:33 +0000 |
commit | cf92ecf6f149730d18d308a8c9c67a8785a0d850 (patch) | |
tree | 418da5ec449bc4e4be8138b5c463ac75f490eae2 /src/soc/amd/common | |
parent | c5b32ee8d86c58e5df01efc27a89570e5389a719 (diff) |
soc/amd: commonize generation of the PIC/APIC mapping tables
Now that we have a common init_tables in all mainboards using AMD SoCs,
both the population of the fch_pic_routing and fch_apic_routing arrays
and the definition of those arrays can be moved to the common AMD SoC
code to not have the code duplicated in all mainboards.
BUG=b:182782749
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Suggested-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Change-Id: I8c65eca258272f0ef7dec3ece6236f5d00954c66
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68853
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc/amd/common')
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/amd_pci_util.h | 4 | ||||
-rw-r--r-- | src/soc/amd/common/block/pci/amd_pci_util.c | 49 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h index c766d501bd..f862bf997d 100644 --- a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h +++ b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h @@ -19,6 +19,8 @@ struct fch_irq_routing { uint8_t apic_irq_num; }; +const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length); + struct pirq_struct { u8 devfn; u8 PIN[4]; /* PINA/B/C/D are index 0/1/2/3 */ @@ -31,8 +33,6 @@ struct irq_idx_name { extern const struct pirq_struct *pirq_data_ptr; extern u32 pirq_data_size; -extern const u8 *intr_data_ptr; -extern const u8 *picr_data_ptr; u8 read_pci_int_idx(u8 index, int mode); void write_pci_int_idx(u8 index, int mode, u8 data); diff --git a/src/soc/amd/common/block/pci/amd_pci_util.c b/src/soc/amd/common/block/pci/amd_pci_util.c index d665a81bc2..ecc0498ef0 100644 --- a/src/soc/amd/common/block/pci/amd_pci_util.c +++ b/src/soc/amd/common/block/pci/amd_pci_util.c @@ -7,11 +7,21 @@ #include <amdblocks/amd_pci_util.h> #include <pc80/i8259.h> #include <soc/amd_pci_int_defs.h> +#include <string.h> + +/* + * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. + * This table is responsible for physically routing the PIC and + * IOAPIC IRQs to the different PCI devices on the system. It + * is read and written via registers 0xC00/0xC01 as an + * Index/Data pair. These values are chipset and mainboard + * dependent and should be updated accordingly. + */ +static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES]; +static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES]; const struct pirq_struct *pirq_data_ptr; u32 pirq_data_size; -const u8 *intr_data_ptr; -const u8 *picr_data_ptr; /* * Read the FCH PCI_INTR registers 0xC00/0xC01 at a @@ -33,6 +43,29 @@ void write_pci_int_idx(u8 index, int mode, u8 data) outb(data, PCI_INTR_DATA); } +static void init_fch_irq_map_tables(void) +{ + const struct fch_irq_routing *mb_irq_map; + size_t mb_fch_irq_mapping_table_size; + size_t i; + + mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size); + + memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing)); + memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing)); + + for (i = 0; i < mb_fch_irq_mapping_table_size; i++) { + if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) { + printk(BIOS_WARNING, + "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n", + mb_irq_map[i].intr_index, i); + continue; + } + fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num; + fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num; + } +} + /* * Write the FCH PCI_INTR registers 0xC00/0xC01 with values * given in global variables intr_data and picr_data. @@ -44,13 +77,13 @@ void write_pci_int_table(void) size_t i, limit; const struct irq_idx_name *idx_name; + init_fch_irq_map_tables(); + idx_name = sb_get_apic_reg_association(&limit); - if (picr_data_ptr == NULL || intr_data_ptr == NULL || - idx_name == NULL) { + if (idx_name == NULL) { printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01" " registers because\n" - "'mainboard_picr_data' or 'mainboard_intr_data'" - " or 'irq_association'\ntables are NULL\n"); + " 'irq_association'\ntables is NULL\n"); return; } @@ -67,11 +100,11 @@ void write_pci_int_table(void) */ for (i = 0 ; i < limit; i++) { byte = idx_name[i].index; - write_pci_int_idx(byte, 0, (u8)picr_data_ptr[byte]); + write_pci_int_idx(byte, 0, fch_pic_routing[byte]); printk(BIOS_DEBUG, "0x%02X\t\t%-20s 0x%02X\t", byte, idx_name[i].name, read_pci_int_idx(byte, 0)); - write_pci_int_idx(byte, 1, (u8)intr_data_ptr[byte]); + write_pci_int_idx(byte, 1, fch_apic_routing[byte]); printk(BIOS_DEBUG, "0x%02X\n", read_pci_int_idx(byte, 1)); } } |