Mike Loptien (mike.loptien@se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5878
-gerrit
commit 6a53c3c699e325aab6deffb7dc9ef6eba13a8218 Author: Mike Loptien mike.loptien@se-eng.com Date: Fri Jun 6 15:21:28 2014 -0600
Persimmon: Change MPTable to use mainboard IRQ routing
With the addition of the mainboard PCI IRQ routing tables for AMD Persimmon, the MPTables can be set to use this information to accurately reflect the real hardware settings of the system. Additionally, the IOAPIC gets defined before the MPTable gets generated so the settings can be read directly from the IOAPIC registers instead of 'guessing' at them as was done before.
Change-Id: I96ec046a2208eddf4b5e442214ff43d2a349ca4d Signed-off-by: Mike Loptien mike.loptien@se-eng.com --- src/mainboard/amd/persimmon/mptable.c | 142 ++++++++++++++++------------------ 1 file changed, 68 insertions(+), 74 deletions(-)
diff --git a/src/mainboard/amd/persimmon/mptable.c b/src/mainboard/amd/persimmon/mptable.c index 6b8aaa6..247fd22 100644 --- a/src/mainboard/amd/persimmon/mptable.c +++ b/src/mainboard/amd/persimmon/mptable.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2011 Advanced Micro Devices, Inc. + * Copyright (C) 2014 Sage Electronic Engineering, LLC. * * 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 @@ -26,124 +27,117 @@ #include <stdint.h> #include <cpu/amd/amdfam14.h> #include <SBPLATFORM.h> +#include <southbridge/amd/cimx/cimx_util.h> +#include <drivers/generic/ioapic/chip.h> +#include <arch/ioapic.h>
extern u8 bus_sb800[6]; - extern u32 apicid_sb800; +extern const u8 * intr_data_ptr;
extern u32 bus_type[256]; extern u32 sbdn_sb800;
-u8 intr_data[] = { - [0x00] = 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, /* INTA# - INTH# */ - [0x08] = 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F, /* Misc-nil,0,1,2, INT from Serial irq */ - [0x10] = 0x09,0x1F,0x1F,0x10,0x1F,0x12,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x12,0x11,0x12,0x11,0x12,0x11,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x11,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x10,0x11,0x12,0x13 -}; - static void *smp_write_config_table(void *v) { struct mp_config_table *mc; int bus_isa; + u32 apicver_sb800;
+ /* Intialize the MP_Table */ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
mptable_init(mc, LOCAL_APIC_ADDR); - memcpy(mc->mpc_oem, "AMD ", 8);
+ /* + * Type 0: Processor Entries: + * LAPIC ID, LAPIC Version, CPU Flags:EN/BP, + * CPU Signature (Stepping, Model, Family), + * Feature Flags + */ smp_write_processors(mc);
+ /* Get Bus Configuration */ get_bus_conf();
+ /* + * Type 1: Bus Entries: + * Bus ID, Bus Type + */ mptable_write_buses(mc, NULL, &bus_isa);
- /* I/O APICs: APIC ID Version State Address */ - - u32 dword; - u8 byte; - - ReadPMIO(SB_PMIOA_REG34, AccWidthUint32, &dword); - dword &= 0xFFFFFFF0; - smp_write_ioapic(mc, apicid_sb800, 0x21, dword); + /* + * Type 2: I/O APICs: + * APIC ID, Version, APIC Flags:EN, Address + */ + apicid_sb800 = (io_apic_read(IO_APIC_ADDR, 0x00) >> 24); /* Get IOAPIC ID */ + apicver_sb800 = (io_apic_read(IO_APIC_ADDR, 0x01) & 0xFF); /* Get IOAPIC version */
- for (byte = 0x0; byte < sizeof(intr_data); byte ++) { - outb(byte | 0x80, 0xC00); - outb(intr_data[byte], 0xC01); - } - - /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ -#define IO_LOCAL_INT(type, intr, apicid, pin) \ - smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); + smp_write_ioapic(mc, apicid_sb800, apicver_sb800, IO_APIC_ADDR);
+ /* + * Type 3: I/O Interrupt Table Entries: + * Int Type, Int Polarity, Int Level, Source Bus ID, + * Source Bus IRQ, Dest APIC ID, Dest PIN# + */ mptable_add_isa_interrupts(mc, bus_isa, apicid_sb800, 0);
/* PCI interrupts are level triggered, and are * associated with a specific bus/device/function tuple. */ -#if !CONFIG_GENERATE_ACPI_TABLES #define PCI_INT(bus, dev, fn, pin) \ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(fn)), apicid_sb800, (pin)) -#else -#define PCI_INT(bus, dev, fn, pin) -#endif
- /* APU Internal Graphic Device*/ - PCI_INT(0x0, 0x01, 0x0, intr_data[0x02]); - PCI_INT(0x0, 0x01, 0x1, intr_data[0x03]); + /* APU Internal Graphic Device */ + PCI_INT(0x0, 0x01, 0x0, intr_data_ptr[PIRQ_C]); + PCI_INT(0x0, 0x01, 0x1, intr_data_ptr[PIRQ_D]); + + /* SMBUS / ACPI */ + PCI_INT(0x0, 0x14, 0x0, intr_data_ptr[PIRQ_SMBUS]); + + /* Southbridge HD Audio */ + PCI_INT(0x0, 0x14, 0x2, intr_data_ptr[PIRQ_HDA]);
- //PCI_INT(0x0, 0x14, 0x1, 0x11); /* IDE. */ - PCI_INT(0x0, 0x14, 0x0, 0x10); - /* Southbridge HD Audio: */ - PCI_INT(0x0, 0x14, 0x2, 0x12); + /* LPC */ + PCI_INT(0x0, 0x14, 0x3, intr_data_ptr[PIRQ_C]);
- PCI_INT(0x0, 0x12, 0x0, intr_data[0x30]); /* USB */ - PCI_INT(0x0, 0x12, 0x1, intr_data[0x31]); - PCI_INT(0x0, 0x13, 0x0, intr_data[0x32]); - PCI_INT(0x0, 0x13, 0x1, intr_data[0x33]); - PCI_INT(0x0, 0x16, 0x0, intr_data[0x34]); - PCI_INT(0x0, 0x16, 0x1, intr_data[0x35]); + /* USB */ + PCI_INT(0x0, 0x12, 0x0, intr_data_ptr[PIRQ_OHCI1]); + PCI_INT(0x0, 0x12, 0x2, intr_data_ptr[PIRQ_EHCI1]); + PCI_INT(0x0, 0x13, 0x0, intr_data_ptr[PIRQ_OHCI2]); + PCI_INT(0x0, 0x13, 0x2, intr_data_ptr[PIRQ_EHCI2]); + PCI_INT(0x0, 0x14, 0x5, intr_data_ptr[PIRQ_OHCI4]);
- /* sata */ - PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]); + /* IDE */ + PCI_INT(0x0, 0x14, 0x1, intr_data_ptr[PIRQ_IDE]);
- /* on board NIC & Slot PCIE. */ + /* SATA */ + PCI_INT(0x0, 0x11, 0x0, intr_data_ptr[PIRQ_SATA]); + + /* on board NIC & Slot PCIE */ + PCI_INT(0x1, 0x0, 0x0, intr_data_ptr[PIRQ_E]); /* Use INTE */ + PCI_INT(0x2, 0x0, 0x0, intr_data_ptr[PIRQ_E]); /* Use INTE */
/* PCI slots */ - /* PCI_SLOT 0. */ - PCI_INT(bus_sb800[1], 0x5, 0x0, 0x14); - PCI_INT(bus_sb800[1], 0x5, 0x1, 0x15); - PCI_INT(bus_sb800[1], 0x5, 0x2, 0x16); - PCI_INT(bus_sb800[1], 0x5, 0x3, 0x17); - - /* PCI_SLOT 1. */ - PCI_INT(bus_sb800[1], 0x6, 0x0, 0x15); - PCI_INT(bus_sb800[1], 0x6, 0x1, 0x16); - PCI_INT(bus_sb800[1], 0x6, 0x2, 0x17); - PCI_INT(bus_sb800[1], 0x6, 0x3, 0x14); - - /* PCI_SLOT 2. */ - PCI_INT(bus_sb800[1], 0x7, 0x0, 0x16); - PCI_INT(bus_sb800[1], 0x7, 0x1, 0x17); - PCI_INT(bus_sb800[1], 0x7, 0x2, 0x14); - PCI_INT(bus_sb800[1], 0x7, 0x3, 0x15); - - PCI_INT(bus_sb800[2], 0x0, 0x0, 0x12); - PCI_INT(bus_sb800[2], 0x0, 0x1, 0x13); - PCI_INT(bus_sb800[2], 0x0, 0x2, 0x14); + /* PCI_SLOT 0 */ + PCI_INT(bus_sb800[1], 0x5, 0x0, intr_data_ptr[PIRQ_E]); /* INTA -> INTE */ + PCI_INT(bus_sb800[1], 0x5, 0x1, intr_data_ptr[PIRQ_F]); /* INTB -> INTF */ + PCI_INT(bus_sb800[1], 0x5, 0x2, intr_data_ptr[PIRQ_G]); /* INTC -> INTG */ + PCI_INT(bus_sb800[1], 0x5, 0x3, intr_data_ptr[PIRQ_H]); /* INTD -> INTH */
/* PCIe PortA */ - PCI_INT(0x0, 0x15, 0x0, 0x10); + PCI_INT(0x0, 0x15, 0x0, intr_data_ptr[PIRQ_E]); /* INTA -> INTE */ /* PCIe PortB */ - PCI_INT(0x0, 0x15, 0x1, 0x11); + PCI_INT(0x0, 0x15, 0x1, intr_data_ptr[PIRQ_F]); /* INTB -> INTF */ /* PCIe PortC */ - PCI_INT(0x0, 0x15, 0x2, 0x12); + PCI_INT(0x0, 0x15, 0x2, intr_data_ptr[PIRQ_G]); /* INTC -> INTG */ /* PCIe PortD */ - PCI_INT(0x0, 0x15, 0x3, 0x13); + PCI_INT(0x0, 0x15, 0x3, intr_data_ptr[PIRQ_H]); /* INTD -> INTH */
/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ +#define IO_LOCAL_INT(type, intr, apicid, pin) \ + smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); + IO_LOCAL_INT(mp_ExtINT, 0x0, MP_APIC_ALL, 0x0); IO_LOCAL_INT(mp_NMI, 0x0, MP_APIC_ALL, 0x1); /* There is no extension information... */ @@ -155,6 +149,6 @@ static void *smp_write_config_table(void *v) unsigned long write_smp_table(unsigned long addr) { void *v; - v = smp_write_floating_table(addr, 0); + v = smp_write_floating_table(addr, 0); /* ADDR, Enable Virtual Wire */ return (unsigned long)smp_write_config_table(v); }