summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/common/amd_pci_util.c83
-rw-r--r--src/soc/amd/common/amd_pci_util.h8
-rw-r--r--src/soc/amd/stoneyridge/include/soc/amd_pci_int_defs.h20
-rw-r--r--src/soc/amd/stoneyridge/southbridge.c59
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;