--- //depot/vendor/freebsd/src/sys/dev/acpica/acpi.c 2004/01/09 13:05:28 +++ //depot/user/jhb/acpipci/dev/acpica/acpi.c 2004/01/13 14:03:34 @@ -194,33 +194,20 @@ } /* - * Detect ACPI, perform early initialisation + * Perform early initialization. */ -static void -acpi_identify(driver_t *driver, device_t parent) +ACPI_STATUS +acpi_Startup(void) { - device_t child; - int error; #ifdef ACPI_DEBUGGER - char *debugpoint; + char *debugpoint; #endif + static int error, started = 0; - ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + if (started) + return_VALUE(error); + started = 1; - if (!cold) - return_VOID; - - /* Check that we haven't been disabled with a hint. */ - if (resource_disabled("acpi", 0)) - return_VOID; - - snprintf(acpi_ca_version, sizeof(acpi_ca_version), "0x%x", - ACPI_CA_VERSION); - - /* Make sure we're not being doubly invoked. */ - if (device_find_child(parent, "acpi", 0) != NULL) - return_VOID; - #if __FreeBSD_version >= 500000 /* Initialise the ACPI mutex */ mtx_init(&acpi_mutex, "ACPI global lock", NULL, MTX_DEF); @@ -237,7 +224,7 @@ #endif if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) { printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error)); - return_VOID; + return_VALUE(error); } #ifdef ACPI_DEBUGGER debugpoint = getenv("debug.acpi.debugger"); @@ -250,9 +237,39 @@ if (ACPI_FAILURE(error = AcpiLoadTables())) { printf("ACPI: table load failed: %s\n", AcpiFormatException(error)); + return_VALUE(error); + } + return_VALUE(AE_OK); +} + +/* + * Detect ACPI, perform early initialisation + */ +static void +acpi_identify(driver_t *driver, device_t parent) +{ + device_t child; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + if (!cold) + return_VOID; + + /* Check that we haven't been disabled with a hint. */ + if (resource_disabled("acpi", 0)) + return_VOID; + + snprintf(acpi_ca_version, sizeof(acpi_ca_version), "0x%x", + ACPI_CA_VERSION); + + /* Make sure we're not being doubly invoked. */ + if (device_find_child(parent, "acpi", 0) != NULL) + return_VOID; + + /* Initialize ACPI-CA. */ + if (ACPI_FAILURE(acpi_Startup())) return_VOID; - } - + /* Attach the actual ACPI device. */ if ((child = BUS_ADD_CHILD(parent, 0, "acpi", 0)) == NULL) { device_printf(parent, "ACPI: could not attach\n"); --- //depot/vendor/freebsd/src/sys/dev/acpica/acpivar.h 2004/01/13 13:30:33 +++ //depot/user/jhb/acpipci/dev/acpica/acpivar.h 2004/01/13 14:03:34 @@ -190,6 +190,7 @@ extern ACPI_STATUS acpi_OverrideInterruptLevel(UINT32 InterruptNumber); extern ACPI_STATUS acpi_SetIntrModel(int model); extern ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state); +extern ACPI_STATUS acpi_Startup(void); extern ACPI_STATUS acpi_Enable(struct acpi_softc *sc); extern ACPI_STATUS acpi_Disable(struct acpi_softc *sc); extern void acpi_UserNotify(const char *subsystem, ACPI_HANDLE h, --- //depot/vendor/freebsd/src/sys/i386/acpica/madt.c 2003/12/08 19:05:30 +++ //depot/user/jhb/acpipci/i386/acpica/madt.c 2004/01/06 10:41:55 @@ -320,13 +320,22 @@ } /* - * Run through the MP table enumerating I/O APICs. + * Enumerate I/O APICs and setup interrupt sources. */ static int madt_setup_io(void) { int i; + /* Try to initialize ACPI so that we can access the FADT. */ + i = acpi_Startup(); + if (ACPI_FAILURE(i)) { + printf("MADT: ACPI Startup failed with %s\n", + AcpiFormatException(i)); + printf("Try disabling either ACPI or apic support.\n"); + panic("Using MADT but ACPI doesn't work"); + } + /* First, we run through adding I/O APIC's. */ madt_walk_table(madt_parse_apics, NULL); @@ -522,6 +531,7 @@ { void *new_ioapic, *old_ioapic; u_int new_pin, old_pin; + int force_lo; if (bootverbose) printf("MADT: intr override: source %u, irq %u\n", @@ -534,9 +544,27 @@ return; } + /* + * If the SCI is remapped to a non-ISA global interrupt, + * force it to level trigger and active-lo polarity. + * If the SCI is identity mapped but has edge trigger and + * active-hi polarity, also force it to use level/lo. + */ + force_lo = 0; + if (intr->Source == AcpiGbl_FADT->SciInt) + if (intr->Interrupt > 15 || (intr->Interrupt == intr->Source && + intr->TriggerMode == TRIGGER_EDGE && + intr->Polarity == POLARITY_ACTIVE_HIGH)) + force_lo = 1; + if (intr->Source != intr->Interrupt) { - /* XXX: This assumes that the SCI uses IRQ 9. */ - if (intr->Interrupt > 15 && intr->Source == 9) + /* + * If the SCI is remapped to a non-ISA global interrupt, + * then override the vector we use to setup and allocate + * the interrupt. + */ + if (intr->Interrupt > 15 && + intr->Source == AcpiGbl_FADT->SciInt) acpi_OverrideInterruptLevel(intr->Interrupt); else ioapic_remap_vector(new_ioapic, new_pin, intr->Source); @@ -548,10 +576,18 @@ intr->Source) ioapic_disable_pin(old_ioapic, old_pin); } - ioapic_set_triggermode(new_ioapic, new_pin, - interrupt_trigger(intr->TriggerMode)); - ioapic_set_polarity(new_ioapic, new_pin, - interrupt_polarity(intr->Polarity)); + if (force_lo) { + printf( + "MADT: Forcing active-lo polarity and level trigger for IRQ %d\n", + intr->Source); + ioapic_set_polarity(new_ioapic, new_pin, 0); + ioapic_set_triggermode(new_ioapic, new_pin, 0); + } else { + ioapic_set_polarity(new_ioapic, new_pin, + interrupt_polarity(intr->Polarity)); + ioapic_set_triggermode(new_ioapic, new_pin, + interrupt_trigger(intr->TriggerMode)); + } } /*