summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-01-07 18:42:59 +0000
committerjhb <jhb@FreeBSD.org>2005-01-07 18:42:59 +0000
commit0e5c952f880c4c15cd8a3cf56719e8e31c37380f (patch)
treec36d6b9875afb1933714e1b686d7a7ae6d8ff7a7 /sys/i386
parentf966b643b6be8aae03f93f40572cacc4e11fecae (diff)
downloadFreeBSD-src-0e5c952f880c4c15cd8a3cf56719e8e31c37380f.zip
FreeBSD-src-0e5c952f880c4c15cd8a3cf56719e8e31c37380f.tar.gz
Fix support for machines with default MP Table configurations:
- Fix the MP Table pci bridge drivers to not probe the configuration table unless we actually have one. Machines using a default configuration do not have such a table. - Only allow default configuration types of 5 (ISA + PCI) and 6 (EISA + PCI) as the others are not likely to work. Types 1 through 4 use an external APIC (probably with 80486 processors) which we certainly do not support, and type 7 uses an MCA bus which has not been tested with the new MP Table code. - Correct the fact that the single I/O APIC in a default configuration has an ID of 2, not 0. - Fix off by one errors in setting the bus types from the default_data[] arrays for default configurations. - Explicitly configure each of the 16 interrupt pins on the sole I/O APIC when using a default configuration. This is especially helpful for type 6 (EISA + PCI) since the EISA interrupts need to have their polarity programmed based on the values in the ELCR. Much thanks to the submitter and tester who endured several rounds of testing to get this fixed. MFC after: 1 week Tested by: Georg Schwarz georg dot schwarz at freenet dot de
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/mptable.c89
1 files changed, 71 insertions, 18 deletions
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index fe8bf45..c327c07 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -163,6 +163,7 @@ static void mptable_hyperthread_fixup(u_int id_mask);
static void mptable_parse_apics_and_busses(void);
static void mptable_parse_apics_and_busses_handler(u_char *entry,
void *arg);
+static void mptable_parse_default_config_ints(void);
static void mptable_parse_ints(void);
static void mptable_parse_ints_handler(u_char *entry, void *arg);
static void mptable_parse_io_int(int_entry_ptr intr);
@@ -251,9 +252,19 @@ found:
mpfps = (mpfps_t)(KERNBASE + x);
/* Map in the configuration table if it exists. */
- if (mpfps->config_type != 0)
+ if (mpfps->config_type != 0) {
+ if (bootverbose)
+ printf(
+ "MP Table version 1.%d found using Default Configuration %d\n",
+ mpfps->spec_rev, mpfps->config_type);
+ if (mpfps->config_type != 5 && mpfps->config_type != 6) {
+ printf(
+ "MP Table Default Configuration %d is unsupported\n",
+ mpfps->config_type);
+ return (ENXIO);
+ }
mpct = NULL;
- else {
+ } else {
if ((uintptr_t)mpfps->pap >= 1024 * 1024) {
printf("%s: Unable to map MP Configuration Table\n",
__func__);
@@ -315,7 +326,7 @@ mptable_setup_local(void)
printf("MPTable: <");
if (mpfps->config_type != 0) {
lapic_init(DEFAULT_APIC_BASE);
- printf("Preset Config %d", mpfps->config_type);
+ printf("Default Configuration %d", mpfps->config_type);
} else {
lapic_init((uintptr_t)mpct->apic_address);
printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id,
@@ -526,13 +537,13 @@ mptable_parse_apics_and_busses(void)
/* Is this a pre-defined config? */
if (mpfps->config_type != 0) {
- ioapics[0] = ioapic_create(DEFAULT_IO_APIC_BASE, 2, 0);
+ ioapics[2] = ioapic_create(DEFAULT_IO_APIC_BASE, 2, 0);
busses[0].bus_id = 0;
- busses[0].bus_type = default_data[mpfps->config_type][2];
+ busses[0].bus_type = default_data[mpfps->config_type - 1][2];
if (mptable_nbusses > 1) {
busses[1].bus_id = 1;
busses[1].bus_type =
- default_data[mpfps->config_type][4];
+ default_data[mpfps->config_type - 1][4];
}
} else
mptable_walk_table(mptable_parse_apics_and_busses_handler,
@@ -760,7 +771,58 @@ mptable_parse_ints_handler(u_char *entry, void *arg __unused)
break;
}
}
-
+
+/*
+ * Configure interrupt pins for a default configuration. For details see
+ * Table 5-2 in Section 5 of the MP Table specification.
+ */
+static void
+mptable_parse_default_config_ints(void)
+{
+ struct INTENTRY entry;
+ int pin;
+
+ /*
+ * All default configs route IRQs from bus 0 to the first 16 pins
+ * of the first I/O APIC with an APIC ID of 2.
+ */
+ entry.type = MPCT_ENTRY_INT;
+ entry.int_flags = INTENTRY_FLAGS_POLARITY_CONFORM |
+ INTENTRY_FLAGS_TRIGGER_CONFORM;
+ entry.src_bus_id = 0;
+ entry.dst_apic_id = 2;
+
+ /* Run through all 16 pins. */
+ for (pin = 0; pin < 16; pin++) {
+ entry.dst_apic_int = pin;
+ switch (pin) {
+ case 0:
+ /* Pin 0 is an ExtINT pin. */
+ entry.int_type = INTENTRY_TYPE_EXTINT;
+ break;
+ case 2:
+ /* IRQ 0 is routed to pin 2. */
+ entry.int_type = INTENTRY_TYPE_INT;
+ entry.src_bus_irq = 0;
+ break;
+ default:
+ /* All other pins are identity mapped. */
+ entry.int_type = INTENTRY_TYPE_INT;
+ entry.src_bus_irq = pin;
+ break;
+ }
+ mptable_parse_io_int(&entry);
+ }
+
+ /* Certain configs disable certain pins. */
+ if (mpfps->config_type == 7)
+ ioapic_disable_pin(ioapics[2], 0);
+ if (mpfps->config_type == 2) {
+ ioapic_disable_pin(ioapics[2], 2);
+ ioapic_disable_pin(ioapics[2], 13);
+ }
+}
+
/*
* Configure the interrupt pins
*/
@@ -775,16 +837,7 @@ mptable_parse_ints(void)
lapic_set_lvt_mode(APIC_ID_ALL, LVT_LINT1, APIC_LVT_DM_NMI);
/* Configure I/O APIC pins. */
- if (mpfps->config_type != 7)
- ioapic_set_extint(ioapics[0], 0);
- else
- ioapic_disable_pin(ioapics[0], 0);
- if (mpfps->config_type != 2)
- ioapic_remap_vector(ioapics[0], 2, 0);
- else
- ioapic_disable_pin(ioapics[0], 2);
- if (mpfps->config_type == 2)
- ioapic_disable_pin(ioapics[0], 13);
+ mptable_parse_default_config_ints();
} else
mptable_walk_table(mptable_parse_ints_handler, NULL);
}
@@ -894,7 +947,7 @@ mptable_pci_probe_table(int bus)
if (bus < 0)
return (EINVAL);
- if (pci0 == -1 || pci0 + bus > mptable_maxbusid)
+ if (mpct == NULL || pci0 == -1 || pci0 + bus > mptable_maxbusid)
return (ENXIO);
if (busses[pci0 + bus].bus_type != PCI)
return (ENXIO);
OpenPOWER on IntegriCloud