diff options
-rw-r--r-- | src/soc/amd/common/amd_pci_util.c | 83 | ||||
-rw-r--r-- | src/soc/amd/common/amd_pci_util.h | 8 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h | 20 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/southbridge.c | 59 |
4 files changed, 119 insertions, 51 deletions
diff --git a/src/soc/amd/common/amd_pci_util.c b/src/soc/amd/common/amd_pci_util.c index 577b5cb8c4..ca022fbdbb 100644 --- a/src/soc/amd/common/amd_pci_util.c +++ b/src/soc/amd/common/amd_pci_util.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Sage Electronic Engineering, LLC. + * Copyright (C) 2017 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +21,6 @@ #include <amd_pci_util.h> #include <pc80/i8259.h> #include <soc/amd_pci_int_defs.h> -#include <amd_pci_int_types.h> const struct pirq_struct *pirq_data_ptr; u32 pirq_data_size; @@ -54,40 +54,38 @@ void write_pci_int_idx(u8 index, int mode, u8 data) */ void write_pci_int_table(void) { - u8 byte; + uint8_t byte; + size_t i, limit; + const struct irq_idx_name *idx_name; - if (picr_data_ptr == NULL || intr_data_ptr == NULL) { + idx_name = sb_get_apic_reg_association(&limit); + if (picr_data_ptr == NULL || idx_name == NULL) { printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01" " registers because\n" - "'mainboard_picr_data' or 'mainboard_intr_data'" - " tables are NULL\n"); + "'mainboard_picr_data' or" + " irq_association' tables are NULL\n"); return; } /* PIC IRQ routine */ - printk(BIOS_DEBUG, "PCI_INTR tables: Writing registers C00/C01 for PIC" - " mode PCI IRQ routing:\n" - "\tPCI_INTR_INDEX\t\tPCI_INTR_DATA\n"); - for (byte = 0 ; byte < FCH_INT_TABLE_SIZE ; byte++) { - if (intr_types[byte]) { - write_pci_int_idx(byte, 0, (u8) picr_data_ptr[byte]); - printk(BIOS_DEBUG, "\t0x%02X %s\t: 0x%02X\n", - byte, intr_types[byte], - read_pci_int_idx(byte, 0)); - } - } - - /* APIC IRQ routine */ - printk(BIOS_DEBUG, "PCI_INTR tables: Writing registers C00/C01 for APIC" - " mode PCI IRQ routing:\n" - "\tPCI_INTR_INDEX\t\tPCI_INTR_DATA\n"); - for (byte = 0 ; byte < FCH_INT_TABLE_SIZE ; byte++) { - if (intr_types[byte]) { - write_pci_int_idx(byte, 1, (u8) intr_data_ptr[byte]); - printk(BIOS_DEBUG, "\t0x%02X %s\t: 0x%02X\n", - byte, intr_types[byte], - read_pci_int_idx(byte, 1)); - } + printk(BIOS_DEBUG, "PCI_INTR tables: Writing registers C00/C01 for" + " PCI IRQ routing:\n" + "\tPCI_INTR_INDEX\t\tPIC mode" + "\tAPIC mode\n"); + /* + * Iterate table idx_name, indexes outside the table are ignored + * (assumed not connected within the chip). For each iteration, + * get the register index "byte" and the name of the associated + * IRQ source for printing. + */ + for (i = 0 ; i < limit; i++) { + byte = idx_name[i].index; + write_pci_int_idx(byte, 0, (u8) picr_data_ptr[byte]); + printk(BIOS_DEBUG, "\t0x%02X %s\t0x%02X\t\t", + byte, idx_name[i].name, + read_pci_int_idx(byte, 0)); + write_pci_int_idx(byte, 1, (u8) intr_data_ptr[byte]); + printk(BIOS_DEBUG, "0x%02X\n", read_pci_int_idx(byte, 1)); } } @@ -108,7 +106,10 @@ void write_pci_cfg_irqs(void) u16 devfn = 0; /* A PCI Device and Function number */ u8 bridged_device = 0; /* This device is on a PCI bridge */ u32 i = 0; + size_t limit; + const struct irq_idx_name *idx_name; + idx_name = sb_get_apic_reg_association(&limit); if (pirq_data_ptr == NULL) { printk(BIOS_WARNING, "Warning: Can't write PCI IRQ assignments" " because 'mainboard_pirq_data' structure does" @@ -172,11 +173,20 @@ void write_pci_cfg_irqs(void) " perhaps this device was" " defined wrong?\n"); continue; - } else if (pci_intr_idx >= FCH_INT_TABLE_SIZE) { - /* Index out of bounds */ - printk(BIOS_ERR, "%s: got 0xC00/0xC01 table index" - " 0x%x, max is 0x%x\n", __func__, - pci_intr_idx, FCH_INT_TABLE_SIZE); + } + /* + * Find the name associated with register [pci_intr_idx] + * and print information. + */ + for (i = 0; i < limit; i++) { + if (idx_name[i].index == pci_intr_idx) + break; + } + if (i == limit) { + printk(BIOS_SPEW, "Got register index 0x%02x" + " undefined in table irq_idx_name,\n" + " perhaps this device was" + " defined wrong?\n", pci_intr_idx); continue; } @@ -208,10 +218,11 @@ void write_pci_cfg_irqs(void) if (bridged_device) printk(BIOS_SPEW, "\tSwizzled to\t: %d (%s)\n", target_pin, pin_to_str(target_pin)); + printk(BIOS_SPEW, "\tPCI_INTR idx\t: 0x%02x (%s)\n" - "\tINT_LINE\t: 0x%X (IRQ %d)\n", - pci_intr_idx, intr_types[pci_intr_idx], - int_line, int_line); + "\tINT_LINE\t: 0x%X (IRQ %d)\n", + pci_intr_idx, idx_name[i].name, + int_line, int_line); } /* for (dev = all_devices) */ printk(BIOS_DEBUG, "PCI_CFG IRQ: Finished writing PCI config space" " IRQ assignments\n"); diff --git a/src/soc/amd/common/amd_pci_util.h b/src/soc/amd/common/amd_pci_util.h index 39ffcedd32..92d27dcca7 100644 --- a/src/soc/amd/common/amd_pci_util.h +++ b/src/soc/amd/common/amd_pci_util.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Sage Electronic Engineering, LLC. + * Copyright (C) 2017 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +18,7 @@ #define __AMD_PCI_UTIL_H__ #include <stdint.h> +#include <soc/amd_pci_int_defs.h> /* FCH index/data registers */ #define PCI_INTR_INDEX 0xc00 @@ -27,6 +29,11 @@ struct pirq_struct { u8 PIN[4]; /* PINA/B/C/D are index 0/1/2/3 */ }; +struct irq_idx_name { + uint8_t index; + const char * const name; +}; + extern const struct pirq_struct *pirq_data_ptr; extern u32 pirq_data_size; extern const u8 *intr_data_ptr; @@ -36,5 +43,6 @@ u8 read_pci_int_idx(u8 index, int mode); void write_pci_int_idx(u8 index, int mode, u8 data); void write_pci_cfg_irqs(void); void write_pci_int_table(void); +const struct irq_idx_name *sb_get_apic_reg_association(size_t *size); #endif /* __AMD_PCI_UTIL_H__ */ diff --git a/src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h b/src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h index a8e75f6327..e160c89283 100644 --- a/src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h +++ b/src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2014 Sage Electronic Engineering, LLC. + * Copyright (C) 2017 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,9 +18,8 @@ #define __AMD_PCI_INT_DEFS_H__ /* - * PIRQ and device routing - these define the index - * into the FCH PCI_INTR 0xC00/0xC01 interrupt - * routing table + * PIRQ and device routing - these define the index into the + * FCH PCI_INTR 0xC00/0xC01 interrupt routing table. */ #define PIRQ_NC 0x1f /* Not Used */ @@ -44,26 +44,18 @@ #define PIRQ_ASF 0x12 /* ASF */ #define PIRQ_HDA 0x13 /* HDA 14h.2 */ #define PIRQ_FC 0x14 /* FC */ -#define PIRQ_GEC 0x15 /* GEC */ #define PIRQ_PMON 0x16 /* Performance Monitor */ #define PIRQ_SD 0x17 /* SD */ +#define PIRQ_SDIO 0x1a /* SDIO */ #define PIRQ_IMC0 0x20 /* IMC INT0 */ #define PIRQ_IMC1 0x21 /* IMC INT1 */ #define PIRQ_IMC2 0x22 /* IMC INT2 */ #define PIRQ_IMC3 0x23 /* IMC INT3 */ #define PIRQ_IMC4 0x24 /* IMC INT4 */ #define PIRQ_IMC5 0x25 /* IMC INT5 */ -#define PIRQ_OHCI1 0x30 /* USB OHCI 12h.0 */ -#define PIRQ_EHCI1 0x31 /* USB EHCI 12h.2 */ -#define PIRQ_OHCI2 0x32 /* USB OHCI 13h.0 */ -#define PIRQ_EHCI2 0x33 /* USB EHCI 13h.2 */ -#define PIRQ_OHCI3 0x34 /* USB OHCI 16h.0 */ -#define PIRQ_EHCI3 0x35 /* USB EHCI 16h.2 */ -#define PIRQ_OHCI4 0x36 /* USB OHCI 14h.5 */ -#define PIRQ_IDE 0x40 /* IDE 14h.1 */ +#define PIRQ_EHCI 0x30 /* USB EHCI 12h.0 */ +#define PIRQ_XHCI 0x34 /* USB XHCI 10h.0 */ #define PIRQ_SATA 0x41 /* SATA 11h.0 */ - -#define FCH_INT_TABLE_SIZE 0x76 #define PIRQ_GPIO 0x62 /* GPIO Controller Interrupt */ #define PIRQ_I2C0 0x70 #define PIRQ_I2C1 0x71 diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index dbf27bc6b8..44dbf62a1c 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2010 Advanced Micro Devices, Inc. + * Copyright (C) 2010-2017 Advanced Micro Devices, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,10 +27,67 @@ #include <amd_pci_util.h> #include <soc/southbridge.h> #include <soc/smi.h> +#include <soc/amd_pci_int_defs.h> #include <fchec.h> #include <delay.h> #include <soc/pci_devs.h> +/* + * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME + * provides a visible association with the index, therefor helping + * maintainability of table. If a new index/name is defined in + * amd_pci_int_defs.h, just add the pair at the end of this table. + * Order is not important. + */ +const static struct irq_idx_name irq_association[] = { + { PIRQ_A, "INTA#\t" }, + { PIRQ_B, "INTB#\t" }, + { PIRQ_C, "INTC#\t" }, + { PIRQ_D, "INTD#\t" }, + { PIRQ_E, "INTE#\t" }, + { PIRQ_F, "INTF#\t" }, + { PIRQ_G, "INTG#\t" }, + { PIRQ_H, "INTH#\t" }, + { PIRQ_MISC, "Misc\t" }, + { PIRQ_MISC0, "Misc0\t" }, + { PIRQ_MISC1, "Misc1\t" }, + { PIRQ_MISC2, "Misc2\t" }, + { PIRQ_SIRQA, "Ser IRQ INTA" }, + { PIRQ_SIRQB, "Ser IRQ INTB" }, + { PIRQ_SIRQC, "Ser IRQ INTC" }, + { PIRQ_SIRQD, "Ser IRQ INTD" }, + { PIRQ_SCI, "SCI\t" }, + { PIRQ_SMBUS, "SMBUS\t" }, + { PIRQ_ASF, "ASF\t" }, + { PIRQ_HDA, "HDA\t" }, + { PIRQ_FC, "FC\t\t" }, + { PIRQ_PMON, "PerMon\t" }, + { PIRQ_SD, "SD\t\t" }, + { PIRQ_SDIO, "SDIO\t" }, + { PIRQ_IMC0, "IMC INT0\t" }, + { PIRQ_IMC1, "IMC INT1\t" }, + { PIRQ_IMC2, "IMC INT2\t" }, + { PIRQ_IMC3, "IMC INT3\t" }, + { PIRQ_IMC4, "IMC INT4\t" }, + { PIRQ_IMC5, "IMC INT5\t" }, + { PIRQ_EHCI, "EHCI\t" }, + { PIRQ_XHCI, "XHCI\t" }, + { PIRQ_SATA, "SATA\t" }, + { PIRQ_GPIO, "GPIO\t" }, + { PIRQ_I2C0, "I2C0\t" }, + { PIRQ_I2C1, "I2C1\t" }, + { PIRQ_I2C2, "I2C2\t" }, + { PIRQ_I2C3, "I2C3\t" }, + { PIRQ_UART0, "UART0\t" }, + { PIRQ_UART1, "UART1\t" }, +}; + +const struct irq_idx_name *sb_get_apic_reg_association(size_t *size) +{ + *size = ARRAY_SIZE(irq_association); + return irq_association; +} + void configure_stoneyridge_uart(void) { u8 byte, byte2; |