[coreboot-gerrit] New patch to review for coreboot: 8ca9a81 MP Spec: Add debugging capabilities

Mike Loptien (mike.loptien@se-eng.com) gerrit at coreboot.org
Thu Jun 12 00:17:51 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/5978

-gerrit

commit 8ca9a8181b94edcc965a69bebeab264576185f57
Author: Mike Loptien <mike.loptien at se-eng.com>
Date:   Wed Jun 11 14:26:10 2014 -0600

    MP Spec: Add debugging capabilities
    
    The MPTable did not have any sort of debug capabilities
    like the ACPI and SMBIOS tables do.  If both BIOS_SPEW or
    BIOS_DEBUG and CONFIG_DEBUG_MP_TABLE are selected, this
    will print out all of the tables that get created by the
    MP Table process.
    
    Also added a function for PCI I/O interrupts since these are
    handled slightly differently than the other I/O interrupt
    entries.  The src_bus_irq field is defined where
     Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3
     Bits 2-6: Originating PCI Device Number
     Bit 7: Reserved
    
    Change-Id: I13a446043c5094a680eb7461ec4b61427b7a7050
    Signed-off-by: Mike Loptien <mike.loptien at se-eng.com>
---
 src/Kconfig                            |  14 ++
 src/arch/x86/boot/mpspec.c             | 387 ++++++++++++++++++++++++++++++---
 src/arch/x86/include/arch/smp/mpspec.h | 182 ++++++++--------
 3 files changed, 458 insertions(+), 125 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 061f63e..31d36e0 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -842,6 +842,20 @@ config DEBUG_ACPI
 
 # Only visible if debug level is DEBUG (7) or SPEW (8) as it does additional
 # printk(BIOS_DEBUG, ...) calls.
+config DEBUG_MP_TABLE
+	prompt "Output verbose MP_Table debug messages" if DEFAULT_CONSOLE_LOGLEVEL_7 || DEFAULT_CONSOLE_LOGLEVEL_8
+	bool
+	default n
+	depends on HAVE_MP_TABLE
+	help
+	  This option enables additional MP_Table related debug messages.
+
+	  Note: This option will slightly increase the size of the coreboot image.
+
+	  If unsure, say N.
+
+# Only visible if debug level is DEBUG (7) or SPEW (8) as it does additional
+# printk(BIOS_DEBUG, ...) calls.
 config REALMODE_DEBUG
 	prompt "Enable debug messages for option ROM execution" if DEFAULT_CONSOLE_LOGLEVEL_7 || DEFAULT_CONSOLE_LOGLEVEL_8
 	bool
diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c
index fc2c1e5..7976f55 100644
--- a/src/arch/x86/boot/mpspec.c
+++ b/src/arch/x86/boot/mpspec.c
@@ -27,6 +27,10 @@
 #include <cpu/x86/lapic.h>
 #include <drivers/generic/ioapic/chip.h>
 
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+#include <lib.h> // hexdump
+#endif
+
 /* Initialize the specified "mc" struct with initial values. */
 void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
 {
@@ -58,6 +62,25 @@ void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
 		mc->mpc_oem[i] = ' ';
 	for (i = MIN(strlen(CONFIG_MAINBOARD_PART_NUMBER), 12); i < 12; i++)
 		mc->mpc_productid[i] = ' ';
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "MP_Tables: Init MP Configuration Table Header:\n"
+			"\tSignature\t\t: %4.4s\n"
+			"\tLength\t\t\t: 0x%x (Only Header, no other entries)\n"
+			"\tMP Specification\t: 0x%x\n"
+			"\tChecksum\t\t: 0x%x (Not calculated yet)\n"
+			"\tOEM ID\t\t\t: %8.8s\n"
+			"\tProduct ID\t\t: %12.12s\n"
+			"\tOEM Table PTR\t\t: 0x%x\n"
+			"\tOEM Table Size\t\t: 0x%x (Not filled in yet)\n"
+			"\tEntry Count\t\t: 0x%x (No entries created yet)\n"
+			"\tMMIO LAPIC Address\t: 0x%x\n"
+			"\tExtended Table Length\t: 0x%x (Not filled in yet)\n"
+			"\tExtended Table Checksum\t: 0x%x (Not calculated yet)\n",
+			mc->mpc_signature, mc->mpc_length, mc->mpc_spec, mc->mpc_checksum,
+			mc->mpc_oem, mc->mpc_productid, mc->mpc_oemptr, mc->mpc_oemsize,
+			mc->mpc_entry_count, mc->mpc_lapic, mc->mpe_length, mc->mpe_checksum);
+#endif
 }
 
 static unsigned char smp_compute_checksum(void *v, int len)
@@ -73,7 +96,7 @@ static unsigned char smp_compute_checksum(void *v, int len)
 	return checksum;
 }
 
-static void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_physptr, unsigned int virtualwire)
+static void *smp_write_floating_table_physaddr(u32 addr, u32 mpf_physptr, unsigned int virtualwire)
 {
 	struct intel_mp_floating *mf;
 	void *v;
@@ -94,6 +117,24 @@ static void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long
 	mf->mpf_feature4 = 0;
 	mf->mpf_feature5 = 0;
 	mf->mpf_checksum = smp_compute_checksum(mf, mf->mpf_length*16);
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "MP_Tables: Add MP Floating Pointer Structure:\n"
+			"\tSignature\t\t: %4.4s\n"
+			"\tPhysical Pointer\t: 0x%x\n"
+			"\tLength\t\t\t: %d Paragraph(s) (16-bytes each)\n"
+			"\tMP Specification\t: 0x%x\n"
+			"\tChecksum\t\t: 0x%x\n"
+			"\tFeature1\t\t: 0x%x (Should be 0)\n"
+			"\tFeature2\t\t: '%s'\n"
+			"\tFeature3\t\t: 0x%x\n"
+			"\tFeature4\t\t: 0x%x\n"
+			"\tFeature5\t\t: 0x%x\n",
+			mf->mpf_signature, mpf_physptr, mf->mpf_length, mf->mpf_specification,
+			mf->mpf_checksum, mf->mpf_feature1, virtualwire?"PIC Mode":"Virtual Wire Mode",
+			mf->mpf_feature3, mf->mpf_feature4,	mf->mpf_feature5);
+#endif
+
 	return v;
 }
 
@@ -101,6 +142,8 @@ void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire)
 {
 	/* 16 byte align the table address */
 	addr = (addr + 0xf) & (~0xf);
+
+	printk(BIOS_INFO, "MP_Tables: Start writing the MP_Tables at 0x%lx\n", addr);
 	return smp_write_floating_table_physaddr(addr, addr + SMP_FLOATING_TABLE_LEN, virtualwire);
 }
 
@@ -108,9 +151,10 @@ void *smp_next_mpc_entry(struct mp_config_table *mc)
 {
 	void *v;
 	v = (void *)(((char *)mc) + mc->mpc_length);
+
 	return v;
 }
-static void smp_add_mpc_entry(struct mp_config_table *mc, unsigned length)
+static void smp_add_mpc_entry(struct mp_config_table *mc, u16 length)
 {
 	mc->mpc_length += length;
 	mc->mpc_entry_count++;
@@ -120,6 +164,7 @@ void *smp_next_mpe_entry(struct mp_config_table *mc)
 {
 	void *v;
 	v = (void *)(((char *)mc) + mc->mpc_length + mc->mpe_length);
+
 	return v;
 }
 static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe)
@@ -127,11 +172,19 @@ static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe)
 	mc->mpe_length += mpe->mpe_length;
 }
 
+/*
+ * Type 0: Processor Entries:
+ * Entry Type, LAPIC ID, LAPIC Version, CPU Flags EN/BP,
+ * CPU Signature (Stepping, Model, Family), Feature Flags
+ */
 void smp_write_processor(struct mp_config_table *mc,
-	unsigned char apicid, unsigned char apicver,
-	unsigned char cpuflag, unsigned int cpufeature,
-	unsigned int featureflag)
+	u8 apicid, u8 apicver, u8 cpuflag,
+	u32 cpufeature, u32 featureflag)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd CPU/LAPIC Entry (Type 0)\n");
+#endif
+
 	struct mpc_config_processor *mpc;
 	mpc = smp_next_mpc_entry(mc);
 	memset(mpc, '\0', sizeof(*mpc));
@@ -141,10 +194,27 @@ void smp_write_processor(struct mp_config_table *mc,
 	mpc->mpc_cpuflag = cpuflag;
 	mpc->mpc_cpufeature = cpufeature;
 	mpc->mpc_featureflag = featureflag;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tID\t\t: 0x%x\n"
+			"\tVersion\t\t: 0x%x\n"
+			"\tFlags\t\t: 0x%x (%s%s)\n"
+			"\tCPU Signature 0x%x:\n"
+			"\t  (Family %d, Model %d, Stepping %d)\n"
+			"\tFeature Flag\t: 0x%x (See CPUID)\n",
+			apicid, apicver, cpuflag,
+			(cpuflag & 0x1) ? "Enabled" : "Disabled",
+			(cpuflag & 0x2) ? ", Bootstrap" : "",
+			cpufeature, (cpufeature >> 8) & 0x0F, (cpufeature  >> 4) & 0x0F,
+			cpufeature & 0x0F, featureflag);
+#endif
+
 	smp_add_mpc_entry(mc, sizeof(*mpc));
 }
 
-/* If we assume a symmetric processor configuration we can
+/*
+ * If we assume a symmetric processor configuration we can
  * get all of the information we need to write the processor
  * entry from the bootstrap processor.
  * Plus I don't think linux really even cares.
@@ -183,8 +253,9 @@ void smp_write_processors(struct mp_config_table *mc)
 				cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
 
 			if(cpu->path.apic.apic_id == order_id) {
-				smp_write_processor(mc, cpu->path.apic.apic_id, apic_version,
-						cpu_flag, cpu_features, cpu_feature_flags
+				smp_write_processor(mc,
+					cpu->path.apic.apic_id, apic_version,
+					cpu_flag, cpu_features, cpu_feature_flags
 				);
 				break;
 			}
@@ -192,22 +263,45 @@ void smp_write_processors(struct mp_config_table *mc)
 	}
 }
 
+/*
+ * Type 1: Bus Entries:
+ * Entry Type, Bus ID, Bus Type
+ */
 static void smp_write_bus(struct mp_config_table *mc,
-	unsigned char id, const char *bustype)
+	u8 id, const char *bustype)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd Bus Entry (Type 1)\n");
+#endif
+
 	struct mpc_config_bus *mpc;
 	mpc = smp_next_mpc_entry(mc);
 	memset(mpc, '\0', sizeof(*mpc));
 	mpc->mpc_type = MP_BUS;
 	mpc->mpc_busid = id;
 	memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype));
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tBus ID\t\t: 0x%x\n"
+			"\tBus Type\t: '%s'\n",
+			id, bustype);
+#endif
+
 	smp_add_mpc_entry(mc, sizeof(*mpc));
 }
 
+/*
+ * Type 2: I/O APIC Entries:
+ * Entry Type, APIC ID, Version,
+ * APIC Flags:EN, Address
+ */
 void smp_write_ioapic(struct mp_config_table *mc,
-	unsigned char id, unsigned char ver,
-	unsigned long apicaddr)
+	u8 id, u8 ver, u32 apicaddr)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd IOAPIC Entry (Type 2)\n");
+#endif
 	struct mpc_config_ioapic *mpc;
 	mpc = smp_next_mpc_entry(mc);
 	memset(mpc, '\0', sizeof(*mpc));
@@ -216,14 +310,98 @@ void smp_write_ioapic(struct mp_config_table *mc,
 	mpc->mpc_apicver = ver;
 	mpc->mpc_flags = MPC_APIC_USABLE;
 	mpc->mpc_apicaddr = apicaddr;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tID\t\t: 0x%x\n"
+			"\tVersion\t\t: 0x%x\n"
+			"\tFlags\t\t: 0x%x (%s)\n"
+			"\tAddress\t\t: 0x%x\n",
+			id, ver, mpc->mpc_flags, mpc->mpc_flags ? "Useable" : "Unusable",
+			apicaddr);
+#endif
+
 	smp_add_mpc_entry(mc, sizeof(*mpc));
 }
 
+/*
+ * Type 3 and 4 MP entries have identical IRQ Types
+ * where an integer corresponds to a type which is
+ * easier to understand as a string
+ */
+const char * smp_irqtype_to_str(u8 irqtype)
+{
+	const char * str[] = {
+			"Vectored INT",
+			"NMI",
+			"SMI",
+			"ExtINT",
+	};
+
+	if (irqtype < 4)
+		return str[irqtype];
+	else
+		return "Unknown IRQ Type";
+}
+
+/*
+ * Type 3 and 4 MP entries have an irqflag field
+ * that has (Polarity << 2) | (Trigger) data.  This
+ * is much easier to read as a string for each MP
+ * entry that uses them
+ */
+char * smp_irqflag_to_str(u16 irqflag)
+{
+	int polarity = (irqflag & 0x3);		/* Polarity is bottom 2 bits */
+	int trigger = (irqflag >> 2) & 0x3;	/* Trigger is next 2 bits */
+	char str[1000];
+	char * str_ptr;
+	int len = 0;
+
+	str_ptr = str;
+
+	/* IRQ Trigger polarity */
+	const char * pol[] = {
+			"Bus Default",
+			"Active High",
+			"Reserved",
+			"Active Low",
+	};
+
+	/* IRQ Trigger mode */
+	const char * trig[] = {
+			"Bus Default",
+			"Edge Triggered",
+			"Reserved",
+			"Level Triggered",
+		};
+
+	/* Create the Polarity|Trigger string */
+	if ((strlen(pol[polarity]) + strlen("|") + strlen(trig[trigger]) + 1) < sizeof(str)) {
+		strcpy(str, pol[polarity]);
+		len = strlen(pol[polarity]);
+		strcpy(str + len, "|");
+		len += strlen("|");
+		strcpy(str + len, trig[trigger]);
+	}
+
+	return str_ptr;
+}
+
+/*
+ * Type 3: I/O Interrupt Table Entries:
+ * Entry Type, Int Type, Int Polarity, Int Level,
+ * Source Bus ID, Source Bus IRQ, Dest APIC ID, Dest PIN#
+ */
 void smp_write_intsrc(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
-	unsigned char srcbus, unsigned char srcbusirq,
-	unsigned char dstapic, unsigned char dstirq)
+	u8 irqtype, u16 irqflag,
+	u8 srcbus, u8 srcbusirq,
+	u8 dstapic, u8 dstirq)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd IO Interrupt Entry (Type 3)\n");
+#endif
+
 	struct mpc_config_intsrc *mpc;
 	mpc = smp_next_mpc_entry(mc);
 	memset(mpc, '\0', sizeof(*mpc));
@@ -234,17 +412,44 @@ void smp_write_intsrc(struct mp_config_table *mc,
 	mpc->mpc_srcbusirq = srcbusirq;
 	mpc->mpc_dstapic = dstapic;
 	mpc->mpc_dstirq = dstirq;
-	smp_add_mpc_entry(mc, sizeof(*mpc));
-#ifdef DEBUG_MPTABLE
-	printk(BIOS_DEBUG, "add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n",
-				srcbus, srcbusirq, dstapic, dstirq);
-	hexdump(__func__, mpc, sizeof(*mpc));
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tIRQ Type\t: 0x%x (%s)\n"
+			"\tIRQ Flags\t: 0x%x (%s)\n"
+			"\tSrc Bus ID\t: 0x%x\n"
+			"\tSrc Bus IRQ\t: 0x%x\n"
+			"\tDest IOAPIC\t: 0x%x\n"
+			"\tDest IOAPIC IRQ\t: 0x%x\n",
+			irqtype, smp_irqtype_to_str(irqtype),
+			irqflag, smp_irqflag_to_str(irqflag),
+			srcbus, srcbusirq, dstapic, dstirq);
 #endif
+
+	smp_add_mpc_entry(mc, sizeof(*mpc));
+}
+
+/*
+ * Type 3: I/O Interrupt Table Entries for PCI Devices:
+ * This has the same fields as 'Type 3: I/O Interrupt Table Entries'
+ * but the Source Bus IRQ field has a slightly different
+ * definition:
+ * Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3
+ * Bits 2-6: Originating PCI Device Number (Not its parent bridge device number)
+ * Bit 7: Reserved
+ */
+void smp_write_pci_intsrc(struct mp_config_table *mc,
+	u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
+	u8 dstapic, u8 dstirq)
+{
+	u8 srcbusirq = (dev << 2) | pirq;
+	printk(BIOS_SPEW, "\tPCI srcbusirq = 0x%x from dev = 0x%x and pirq = %x\n", srcbusirq, dev, pirq);
+	smp_write_intsrc(mc, irqtype, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, srcbus,
+			srcbusirq, dstapic, dstirq);
 }
 
 void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
-	struct device *dev,
+	u8 irqtype, u16 irqflag, struct device *dev,
 	unsigned char dstapic, unsigned char *dstirq)
 {
 	struct device *child;
@@ -293,11 +498,21 @@ next:
 	}
 }
 
+/*
+ * Type 4: Local Interrupt Assignment Entries:
+ * Entry Type, Int Type, Int Polarity, Int Level,
+ * Source Bus ID, Source Bus IRQ, Dest LAPIC ID,
+ * Dest LAPIC LINTIN#
+ */
 void smp_write_lintsrc(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
-	unsigned char srcbusid, unsigned char srcbusirq,
-	unsigned char destapic, unsigned char destapiclint)
+	u8 irqtype, u16 irqflag,
+	u8 srcbusid, u8 srcbusirq,
+	u8 destapic, u8 destapiclint)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd Local Interrupt Entry (Type 4)\n");
+#endif
+
 	struct mpc_config_lintsrc *mpc;
 	mpc = smp_next_mpc_entry(mc);
 	memset(mpc, '\0', sizeof(*mpc));
@@ -308,14 +523,37 @@ void smp_write_lintsrc(struct mp_config_table *mc,
 	mpc->mpc_srcbusirq = srcbusirq;
 	mpc->mpc_destapic = destapic;
 	mpc->mpc_destapiclint = destapiclint;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tIRQ Type\t: 0x%x (%s)\n"
+			"\tIRQ Flags\t: 0x%x (%s)\n"
+			"\tSrc Bus ID\t: 0x%x\n"
+			"\tSrc Bus IRQ\t: 0x%x\n"
+			"\tDest LAPIC\t: 0x%x\n"
+			"\tDest LAPIC IRQ\t: 0x%x\n",
+			irqtype, smp_irqtype_to_str(irqtype),
+			irqflag, smp_irqflag_to_str(irqflag),
+			srcbusid, srcbusirq, destapic, destapiclint);
+#endif
+
 	smp_add_mpc_entry(mc, sizeof(*mpc));
 }
 
+/*
+ * Type 128: System Address Space Mapping Entries
+ * Entry Type, Entry Length, Bus ID, Address Type,
+ * Address Base Lo/Hi, Address Length Lo/Hi
+ */
 void smp_write_address_space(struct mp_config_table *mc,
-	unsigned char busid, unsigned char address_type,
-	unsigned int address_base_low, unsigned int address_base_high,
-	unsigned int address_length_low, unsigned int address_length_high)
+	u8 busid, u8 address_type,
+	u32 address_base_low, u32 address_base_high,
+	u32 address_length_low, u32 address_length_high)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd Address Space Mapping Entry (Type 128)\n");
+#endif
+
 	struct mp_exten_system_address_space *mpe;
 	mpe = smp_next_mpe_entry(mc);
 	memset(mpe, '\0', sizeof(*mpe));
@@ -327,14 +565,33 @@ void smp_write_address_space(struct mp_config_table *mc,
 	mpe->mpe_address_base_high = address_base_high;
 	mpe->mpe_address_length_low  = address_length_low;
 	mpe->mpe_address_length_high = address_length_high;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tEntry Length\t: 0x%x\n"
+			"\tBus ID\t\t: 0x%x\n"
+			"\tAddress Type\t: 0x%x\n"
+			"\tAddress Base\t: 0x%x%x\n"
+			"\tAddress Length\t: 0x%x%x\n",
+			mpe->mpe_length, busid, address_type, address_base_high, address_base_low,
+			address_length_high, address_length_low);
+#endif
+
 	smp_add_mpe_entry(mc, (mpe_t)mpe);
 }
 
-
+/*
+ * Type 129: Bus Hierarchy Descriptor Entry
+ * Entry Type, Entry Length, Bus ID, Bus Info,
+ * Parent Bus ID
+ */
 void smp_write_bus_hierarchy(struct mp_config_table *mc,
-	unsigned char busid, unsigned char bus_info,
-	unsigned char parent_busid)
+	u8 busid, u8 bus_info, u8 parent_busid)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd Bus Hierarchy Entry (Type 129)\n");
+#endif
+
 	struct mp_exten_bus_hierarchy *mpe;
 	mpe = smp_next_mpe_entry(mc);
 	memset(mpe, '\0', sizeof(*mpe));
@@ -343,13 +600,32 @@ void smp_write_bus_hierarchy(struct mp_config_table *mc,
 	mpe->mpe_busid = busid;
 	mpe->mpe_bus_info = bus_info;
 	mpe->mpe_parent_busid = parent_busid;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tEntry Length\t: 0x%x\n"
+			"\tBus ID\t\t: 0x%x\n"
+			"\tBus Info\t: 0x%x\n"
+			"\tParent Bus ID\t: 0x%x\n",
+			mpe->mpe_length, busid, bus_info, parent_busid);
+#endif
+
 	smp_add_mpe_entry(mc, (mpe_t)mpe);
 }
 
+/*
+ * Type 130: Compatibility Bus Address Space Modifier Entry
+ * Entry Type, Entry Length, Bus ID, Address Modifier
+ * Predefined Range List
+ */
 void smp_write_compatibility_address_space(struct mp_config_table *mc,
-	unsigned char busid, unsigned char address_modifier,
-	unsigned int range_list)
+	u8 busid, u8 address_modifier,
+	u32 range_list)
 {
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "\n\tAdd Compatibility Address Space Entry (Type 130)\n");
+#endif
+
 	struct mp_exten_compatibility_address_space *mpe;
 	mpe = smp_next_mpe_entry(mc);
 	memset(mpe, '\0', sizeof(*mpe));
@@ -358,6 +634,16 @@ void smp_write_compatibility_address_space(struct mp_config_table *mc,
 	mpe->mpe_busid = busid;
 	mpe->mpe_address_modifier = address_modifier;
 	mpe->mpe_range_list = range_list;
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_SPEW,
+			"\tEntry Length\t: 0x%x\n"
+			"\tBus ID\t\t: 0x%x\n"
+			"\tAddress Modifier: 0x%x\n"
+			"\tRange List\t: 0x%x\n",
+			mpe->mpe_length, busid, address_modifier, range_list);
+#endif
+
 	smp_add_mpe_entry(mc, (mpe_t)mpe);
 }
 
@@ -424,10 +710,41 @@ void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_
 
 void *mptable_finalize(struct mp_config_table *mc)
 {
-	mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+	void *last_mpc_entry = smp_next_mpc_entry(mc);
+	void *last_mpe_entry = smp_next_mpe_entry(mc);
+
+	mc->mpe_checksum = smp_compute_checksum(last_mpc_entry, mc->mpe_length);
 	mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
-	printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
-	return smp_next_mpe_entry(mc);
+	printk(BIOS_INFO, "MP_Tables: Finished writing the MP_Table from 0x%p - 0x%p\n", mc, last_mpe_entry);
+
+#if IS_ENABLED(CONFIG_DEBUG_MP_TABLE)
+	printk(BIOS_DEBUG, "MP_Tables: Final MP Configuration Table Header:\n"
+			"\tSignature\t\t: %4.4s\n"
+			"\tLength\t\t\t: 0x%x\n"
+			"\tMP Specification\t: 0x%x\n"
+			"\tChecksum\t\t: 0x%x\n"
+			"\tOEM ID\t\t\t: %8.8s\n"
+			"\tProduct ID\t\t: %12.12s\n"
+			"\tOEM Table PTR\t\t: 0x%x\n"
+			"\tOEM Table Size\t\t: 0x%x\n"
+			"\tEntry Count\t\t: 0x%x\n"
+			"\tMMIO LAPIC Address\t: 0x%x\n"
+			"\tExtended Table Length\t: 0x%x\n"
+			"\tExtended Table Checksum\t: 0x%x\n",
+			mc->mpc_signature, mc->mpc_length, mc->mpc_spec, mc->mpc_checksum,
+			mc->mpc_oem, mc->mpc_productid, mc->mpc_oemptr, mc->mpc_oemsize,
+			mc->mpc_entry_count, mc->mpc_lapic, mc->mpe_length, mc->mpe_checksum);
+
+	printk(BIOS_SPEW, "\nMP_Tables: Hexdump of the MP Configuration Table (0x%x bytes):\n", mc->mpc_length);
+	hexdump32(BIOS_SPEW, mc, mc->mpc_length / 4);
+
+	if(mc->mpe_length){
+		printk(BIOS_SPEW, "\nMP_Tables: Hexdump of the MP Extended Table (0x%x bytes):\n", mc->mpe_length);
+		hexdump32(BIOS_SPEW, last_mpc_entry, mc->mpe_length / 4);
+	}
+#endif
+
+	return last_mpe_entry;
 }
 
 unsigned long __attribute__((weak)) write_smp_table(unsigned long addr)
diff --git a/src/arch/x86/include/arch/smp/mpspec.h b/src/arch/x86/include/arch/smp/mpspec.h
index 4675977..c546295 100644
--- a/src/arch/x86/include/arch/smp/mpspec.h
+++ b/src/arch/x86/include/arch/smp/mpspec.h
@@ -45,36 +45,36 @@
 
 struct intel_mp_floating
 {
-	char mpf_signature[4];		/* "_MP_" 			*/
-	unsigned long mpf_physptr;	/* Configuration table address	*/
-	unsigned char mpf_length;	/* Our length (paragraphs)	*/
-	unsigned char mpf_specification;/* Specification version	*/
-	unsigned char mpf_checksum;	/* Checksum (makes sum 0)	*/
-	unsigned char mpf_feature1;	/* Standard or configuration ? 	*/
-	unsigned char mpf_feature2;	/* Bit7 set for IMCR|PIC	*/
-	unsigned char mpf_feature3;	/* Unused (0)			*/
-	unsigned char mpf_feature4;	/* Unused (0)			*/
-	unsigned char mpf_feature5;	/* Unused (0)			*/
+	char mpf_signature[4];		/* "_MP_" */
+	u32	mpf_physptr;	/* Configuration table address */
+	u8	mpf_length;		/* Our length (paragraphs) */
+	u8	mpf_specification;/* Specification version */
+	u8	mpf_checksum;	/* Checksum (makes sum 0) */
+	u8	mpf_feature1;	/* Predefined or Unique configuration? */
+	u8	mpf_feature2;	/* Bit7 set for IMCR/PIC */
 #define MP_FEATURE_VIRTUALWIRE (0 << 7)
 #define MP_FEATURE_PIC         (1 << 7)
+	u8	mpf_feature3;	/* Unused (0) */
+	u8	mpf_feature4;	/* Unused (0) */
+	u8	mpf_feature5;	/* Unused (0) */
 } __attribute__((packed));
 
 struct mp_config_table
 {
 	char mpc_signature[4];
 #define MPC_SIGNATURE "PCMP"
-	unsigned short mpc_length;	/* Size of table */
-	char  mpc_spec;			/* 0x01 */
-	char  mpc_checksum;
+	u16 mpc_length;	/* Size of table */
+	u8  mpc_spec;			/* 0x01 */
+	u8  mpc_checksum;
 	char  mpc_oem[8];
 	char  mpc_productid[12];
-	unsigned long mpc_oemptr;	/* 0 if not present */
-	unsigned short mpc_oemsize;	/* 0 if not present */
-	unsigned short mpc_entry_count;
-	unsigned long mpc_lapic;	/* APIC address */
-	unsigned short mpe_length;	/* Extended Table size */
-	unsigned char mpe_checksum;	/* Extended Table checksum */
-	unsigned char reserved;
+	u32	mpc_oemptr;	/* 0 if not present */
+	u16	mpc_oemsize;	/* 0 if not present */
+	u16	mpc_entry_count;
+	u32	mpc_lapic;	/* APIC address */
+	u16	mpe_length;	/* Extended Table size */
+	u8	mpe_checksum;	/* Extended Table checksum */
+	u8	reserved;
 } __attribute__((packed));
 
 /* Followed by entries */
@@ -87,25 +87,25 @@ struct mp_config_table
 
 struct mpc_config_processor
 {
-	unsigned char mpc_type;
-	unsigned char mpc_apicid;	/* Local APIC number */
-	unsigned char mpc_apicver;	/* Its versions */
-	unsigned char mpc_cpuflag;
+	u8	mpc_type;
+	u8	mpc_apicid;	/* Local APIC number */
+	u8	mpc_apicver;	/* Its versions */
+	u8	mpc_cpuflag;
 #define MPC_CPU_ENABLED		1	/* Processor is available */
 #define MPC_CPU_BOOTPROCESSOR	2	/* Processor is the BP */
-	unsigned long mpc_cpufeature;
+	u32	mpc_cpufeature;
 #define MPC_CPU_STEPPING_MASK 0x0F
 #define MPC_CPU_MODEL_MASK	0xF0
 #define MPC_CPU_FAMILY_MASK	0xF00
-	unsigned long mpc_featureflag;	/* CPUID feature value */
-	unsigned long mpc_reserved[2];
+	u32	mpc_featureflag;	/* CPUID feature value */
+	u32	mpc_reserved[2];
 } __attribute__((packed));
 
 struct mpc_config_bus
 {
-	unsigned char mpc_type;
-	unsigned char mpc_busid;
-	unsigned char mpc_bustype[6];
+	u8 mpc_type;
+	u8 mpc_busid;
+	u8 mpc_bustype[6];
 } __attribute__((packed));
 
 #define BUSTYPE_EISA	"EISA"
@@ -118,23 +118,23 @@ struct mpc_config_bus
 
 struct mpc_config_ioapic
 {
-	unsigned char mpc_type;
-	unsigned char mpc_apicid;
-	unsigned char mpc_apicver;
-	unsigned char mpc_flags;
+	u8	mpc_type;
+	u8	mpc_apicid;
+	u8	mpc_apicver;
+	u8	mpc_flags;
 #define MPC_APIC_USABLE		0x01
-	unsigned long mpc_apicaddr;
+	u32	mpc_apicaddr;
 } __attribute__((packed));
 
 struct mpc_config_intsrc
 {
-	unsigned char mpc_type;
-	unsigned char mpc_irqtype;
-	unsigned short mpc_irqflag;
-	unsigned char mpc_srcbus;
-	unsigned char mpc_srcbusirq;
-	unsigned char mpc_dstapic;
-	unsigned char mpc_dstirq;
+	u8	mpc_type;
+	u8	mpc_irqtype;
+	u16	mpc_irqflag;
+	u8	mpc_srcbus;
+	u8	mpc_srcbusirq;
+	u8	mpc_dstapic;
+	u8	mpc_dstirq;
 } __attribute__((packed));
 
 enum mp_irq_source_types {
@@ -156,14 +156,14 @@ enum mp_irq_source_types {
 
 struct mpc_config_lintsrc
 {
-	unsigned char mpc_type;
-	unsigned char mpc_irqtype;
-	unsigned short mpc_irqflag;
-	unsigned char mpc_srcbusid;
-	unsigned char mpc_srcbusirq;
-	unsigned char mpc_destapic;
+	u8	mpc_type;
+	u8	mpc_irqtype;
+	u16	mpc_irqflag;
+	u8	mpc_srcbusid;
+	u8	mpc_srcbusirq;
+	u8	mpc_destapic;
 #define MP_APIC_ALL	0xFF
-	unsigned char mpc_destapiclint;
+	u8	mpc_destapiclint;
 } __attribute__((packed));
 
 /*
@@ -194,44 +194,44 @@ enum mp_bustype {
 #define	MPE_COMPATIBILITY_ADDRESS_SPACE	0x82
 
 struct mp_exten_config {
-	unsigned char mpe_type;
-	unsigned char mpe_length;
+	u8 mpe_type;
+	u8 mpe_length;
 } __attribute__((packed));
 
 typedef struct mp_exten_config *mpe_t;
 
 struct mp_exten_system_address_space {
-	unsigned char mpe_type;
-	unsigned char mpe_length;
-	unsigned char mpe_busid;
-	unsigned char mpe_address_type;
+	u8 mpe_type;
+	u8 mpe_length;
+	u8 mpe_busid;
+	u8 mpe_address_type;
 #define ADDRESS_TYPE_IO       0
 #define ADDRESS_TYPE_MEM      1
 #define ADDRESS_TYPE_PREFETCH 2
-	unsigned int  mpe_address_base_low;
-	unsigned int  mpe_address_base_high;
-	unsigned int  mpe_address_length_low;
-	unsigned int  mpe_address_length_high;
+	u32  mpe_address_base_low;
+	u32  mpe_address_base_high;
+	u32  mpe_address_length_low;
+	u32  mpe_address_length_high;
 } __attribute__((packed));
 
 struct mp_exten_bus_hierarchy {
-	unsigned char mpe_type;
-	unsigned char mpe_length;
-	unsigned char mpe_busid;
-	unsigned char mpe_bus_info;
+	u8 mpe_type;
+	u8 mpe_length;
+	u8 mpe_busid;
+	u8 mpe_bus_info;
 #define BUS_SUBTRACTIVE_DECODE 1
-	unsigned char mpe_parent_busid;
-	unsigned char reserved[3];
+	u8 mpe_parent_busid;
+	u8 reserved[3];
 } __attribute__((packed));
 
 struct mp_exten_compatibility_address_space {
-	unsigned char mpe_type;
-	unsigned char mpe_length;
-	unsigned char mpe_busid;
-	unsigned char mpe_address_modifier;
+	u8 mpe_type;
+	u8 mpe_length;
+	u8 mpe_busid;
+	u8 mpe_address_modifier;
 #define ADDRESS_RANGE_SUBTRACT 1
 #define ADDRESS_RANGE_ADD      0
-	unsigned int  mpe_range_list;
+	u32  mpe_range_list;
 #define RANGE_LIST_IO_ISA	0
 	/* X100 - X3FF
 	 * X500 - X7FF
@@ -251,40 +251,42 @@ struct mp_exten_compatibility_address_space {
 } __attribute__((packed));
 
 void mptable_init(struct mp_config_table *mc, u32 lapic_addr);
-
 void *smp_next_mpc_entry(struct mp_config_table *mc);
 void *smp_next_mpe_entry(struct mp_config_table *mc);
 
 void smp_write_processor(struct mp_config_table *mc,
-	unsigned char apicid, unsigned char apicver,
-	unsigned char cpuflag, unsigned int cpufeature,
-	unsigned int featureflag);
+	u8 apicid, u8 apicver,
+	u8 cpuflag, u32 cpufeature,
+	u32 featureflag);
 void smp_write_processors(struct mp_config_table *mc);
 void smp_write_ioapic(struct mp_config_table *mc,
-	unsigned char id, unsigned char ver,
-	unsigned long apicaddr);
+	u8 id, u8 ver, u32 apicaddr);
+const char * smp_irqtype_to_str(u8 irqtype);
+char * smp_irqflag_to_str(u16 irqflag);
 void smp_write_intsrc(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
-	unsigned char srcbus, unsigned char srcbusirq,
-	unsigned char dstapic, unsigned char dstirq);
+	u8 irqtype, u16 irqflag, u8 srcbus, u8 srcbusirq,
+	u8 dstapic, u8 dstirq);
+void smp_write_pci_intsrc(struct mp_config_table *mc,
+	u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
+	u8 dstapic, u8 dstirq);
 void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
+	u8 irqtype, u16 irqflag,
 	struct device *dev,
 	unsigned char dstapic, unsigned char *dstirq);
 void smp_write_lintsrc(struct mp_config_table *mc,
-	unsigned char irqtype, unsigned short irqflag,
-	unsigned char srcbusid, unsigned char srcbusirq,
-	unsigned char destapic, unsigned char destapiclint);
+	u8 irqtype, u16 irqflag,
+	u8 srcbusid, u8 srcbusirq,
+	u8 destapic, u8 destapiclint);
 void smp_write_address_space(struct mp_config_table *mc,
-	unsigned char busid, unsigned char address_type,
-	unsigned int address_base_low, unsigned int address_base_high,
-	unsigned int address_length_low, unsigned int address_length_high);
+	u8 busid, u8 address_type,
+	u32 address_base_low, u32 address_base_high,
+	u32 address_length_low, u32 address_length_high);
 void smp_write_bus_hierarchy(struct mp_config_table *mc,
-	unsigned char busid, unsigned char bus_info,
-	unsigned char parent_busid);
+	u8 busid, u8 bus_info,
+	u8 parent_busid);
 void smp_write_compatibility_address_space(struct mp_config_table *mc,
-	unsigned char busid, unsigned char address_modifier,
-	unsigned int range_list);
+	u8 busid, u8 address_modifier,
+	u32 range_list);
 void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire);
 unsigned long write_smp_table(unsigned long addr);
 



More information about the coreboot-gerrit mailing list