[coreboot] [PATCH] make I/O APIC IDs and processor APIC IDs unique (asus/m4a785-m)

Scott Duplichan scott at notabs.org
Wed Sep 15 05:42:08 CEST 2010

For the AMD SB700 projects, the SB ioapic id is being assigned the same
value as one of the processor core local apic ids. Apparently this is not
such a serious problem as I had once thought. On the other hand, AMD
recommends using a unique value for each apic id.

Assigning a unique id to the SB ioapic is not as simple as choosing the
next biggest available value, because the ioapic is traditionally a 4-bit
value. Though the south bridge has an option for an 8-bit ioapic id,
using such a value might confuse older operating systems. Choosing the
next available id value for the ioapic works when the number of processor
cores is small, and that is what the AMD BKDG recommends. If this would
result in an ioapic id that exceeds 4 bits, the recommendation is to lift
the processor local apic id numbering so that ioapics can be assigned
values starting at zero. The patch below attempts to implement these
recommendations. The case of lifting local apic ids has not been tested.
In order to meet the 4-bit ioapic id limit without lifting the processor
local apic id values, the patch reduces MAX_PHYSICAL_CPUS from 2 to 1,
which is consistent with the currently supported boards and processors.
The patch is for asus/m4a785-m, but can be adapted for other supported
sb700 desktop projects. Tested by booting amd/m4a785-m/seabios to win7
on simnow. The initial and final ioapic id, as well as the value in the
acpi apic table, are 8.

Signed-off-by: Scott Duplichan <scott at notabs.org>

Index: src/southbridge/amd/sb700/sb700_sm.c
--- src/southbridge/amd/sb700/sb700_sm.c	(revision 5814)
+++ src/southbridge/amd/sb700/sb700_sm.c	(working copy)
@@ -57,12 +57,20 @@
 	printk(BIOS_INFO, "sm_init().\n");
 	ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0);	/* some like mem resource, but does not have  enable bit */
-	/* Don't rename APIC ID */
-	/* TODO: We should call setup_ioapic() here. But kernel hangs if cpu is K8.
-	 * We need to check out why and change back. */
+   /* I/O APIC IDs are normally limited to 4-bits. Enforce this limit. */
+	/* Assign the ioapic ID the next available number after the processor core local APIC IDs */
+	setup_ioapic(ioapic_base, CONFIG_MAX_CPUS * CONFIG_MAX_PHYSICAL_CPUS);
+   #elif (CONFIG_APIC_ID_OFFSET > 0)
+   /* Assign the ioapic ID the value 0. Processor APIC IDs follow. */ 
+	setup_ioapic(ioapic_base, 0);
+   #else
+   #error "The processor APIC IDs must be lifted to make room for the I/O APIC ID"
+   #endif
-	/* 2.10 Interrupt Routing/Filtering */
+ 	/* 2.10 Interrupt Routing/Filtering */
 	dword = pci_read_config8(dev, 0x62);
 	dword |= 3;
 	pci_write_config8(dev, 0x62, dword);
Index: src/mainboard/asus/m4a785-m/Kconfig
--- src/mainboard/asus/m4a785-m/Kconfig	(revision 5814)
+++ src/mainboard/asus/m4a785-m/Kconfig	(working copy)
@@ -49,7 +49,7 @@
-	default 2
+	default 1
Index: src/mainboard/asus/m4a785-m/acpi_tables.c
--- src/mainboard/asus/m4a785-m/acpi_tables.c	(revision 5814)
+++ src/mainboard/asus/m4a785-m/acpi_tables.c	(working copy)
@@ -70,7 +70,13 @@
 	current = acpi_create_madt_lapics(current);
 	/* Write SB700 IOAPIC, only one */
-	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2,
+   #else
+   #define IO_APIC_ID 0
+   #endif
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+					   IO_APIC_ID,
 					   IO_APIC_ADDR, 0);
 	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)

More information about the coreboot mailing list