[coreboot-gerrit] Patch set updated for coreboot: d7ea45d Persimmon: Change MPTable to use mainboard IRQ routing

Mike Loptien (mike.loptien@se-eng.com) gerrit at coreboot.org
Thu Jun 12 00:17:48 CEST 2014


Mike Loptien (mike.loptien at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5878

-gerrit

commit d7ea45d80136989a9109a7da52068713cd362ce5
Author: Mike Loptien <mike.loptien at 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 at se-eng.com>
---
 src/mainboard/amd/persimmon/get_bus_conf.c |  11 ++-
 src/mainboard/amd/persimmon/mptable.c      | 140 ++++++++++++++---------------
 2 files changed, 75 insertions(+), 76 deletions(-)

diff --git a/src/mainboard/amd/persimmon/get_bus_conf.c b/src/mainboard/amd/persimmon/get_bus_conf.c
index 258d895..ac65a1d 100644
--- a/src/mainboard/amd/persimmon/get_bus_conf.c
+++ b/src/mainboard/amd/persimmon/get_bus_conf.c
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <cpu/amd/amdfam14.h>
 #include "agesawrapper.h"
+#include <arch/ioapic.h>
 #if CONFIG_AMD_SB_CIMX
 #include <sb_cimx.h>
 #endif
@@ -36,6 +37,7 @@
 u8 bus_isa;
 u8 bus_sb800[6];
 u32 apicid_sb800;
+u32 apicver_sb800;
 
 /*
 * Here you only need to set value in pci1234 for HT-IO that could be installed or not
@@ -138,7 +140,14 @@ void get_bus_conf(void)
 	/* I/O APICs:    APIC ID Version State   Address */
 	bus_isa = 10;
 	apicid_base = CONFIG_MAX_CPUS;
-	apicid_sb800 = apicid_base;
+
+	/*
+	 * By the time this function gets called, the IOAPIC registers
+	 * have been written so they can be read to get the correct
+	 * APIC ID and Version
+	 */
+	apicid_sb800 = (io_apic_read(IO_APIC_ADDR, 0x00) >> 24);
+	apicver_sb800 = (io_apic_read(IO_APIC_ADDR, 0x01) & 0xFF);
 
 #if CONFIG_AMD_SB_CIMX
 	sb_Late_Post();
diff --git a/src/mainboard/amd/persimmon/mptable.c b/src/mainboard/amd/persimmon/mptable.c
index 6b8aaa6..8639617 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,113 @@
 #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 u32 apicver_sb800;
 
 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;
 
+	/* 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);
-
-	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));
+	/*
+	 * Type 2: I/O APICs:
+	 * APIC ID, Version, APIC Flags:EN, Address
+	 */
+	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]);
 
-	//PCI_INT(0x0, 0x14, 0x1, 0x11); /* IDE. */
-	PCI_INT(0x0, 0x14, 0x0, 0x10);
-	/* Southbridge HD Audio: */
-	PCI_INT(0x0, 0x14, 0x2, 0x12);
+	/* Southbridge HD Audio */
+	PCI_INT(0x0, 0x14, 0x2, intr_data_ptr[PIRQ_HDA]);
 
-	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]);
+	/* LPC */
+	PCI_INT(0x0, 0x14, 0x3, intr_data_ptr[PIRQ_C]);
 
-	/* sata */
-	PCI_INT(0x0, 0x11, 0x0, intr_data[0x41]);
+	/* 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]);
 
-	/* on board NIC & Slot PCIE.	*/
+	 /* IDE */
+	PCI_INT(0x0, 0x14, 0x1, intr_data_ptr[PIRQ_IDE]);
+
+	/* 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 +145,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);
 }



More information about the coreboot-gerrit mailing list