We need to specify the intended interrupt model with ACPI so that we get the
correct PCI IRQ routing table for that mode. With this, we finally get the right PIRQ <-> Global System Interrupt mapping and can therefore program the right IO APIC entries. The only missing part now is to fix up the pci_info of the devices with the then active GSI. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41338 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fa0af37702
commit
1882d05b95
@ -83,6 +83,12 @@
|
|||||||
#define PIC_NUM_INTS 0x0f
|
#define PIC_NUM_INTS 0x0f
|
||||||
|
|
||||||
|
|
||||||
|
// ACPI interrupt models
|
||||||
|
#define ACPI_INTERRUPT_MODEL_PIC 0
|
||||||
|
#define ACPI_INTERRUPT_MODEL_APIC 1
|
||||||
|
#define ACPI_INTERRUPT_MODEL_SAPIC 2
|
||||||
|
|
||||||
|
|
||||||
// Definitions for a 82093AA IO APIC controller
|
// Definitions for a 82093AA IO APIC controller
|
||||||
#define IO_APIC_IDENTIFICATION 0x00
|
#define IO_APIC_IDENTIFICATION 0x00
|
||||||
#define IO_APIC_VERSION 0x01
|
#define IO_APIC_VERSION 0x01
|
||||||
@ -571,6 +577,21 @@ ioapic_map(kernel_args* args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
acpi_set_interrupt_model(acpi_module_info* acpiModule, uint32 interruptModel)
|
||||||
|
{
|
||||||
|
acpi_object_type model;
|
||||||
|
model.object_type = ACPI_TYPE_INTEGER;
|
||||||
|
model.data.integer = interruptModel;
|
||||||
|
|
||||||
|
acpi_objects parameter;
|
||||||
|
parameter.count = 1;
|
||||||
|
parameter.pointer = &model;
|
||||||
|
|
||||||
|
return acpiModule->evaluate_method(NULL, "\\_PIC", ¶meter, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ioapic_init(kernel_args* args)
|
ioapic_init(kernel_args* args)
|
||||||
{
|
{
|
||||||
@ -609,13 +630,21 @@ ioapic_init(kernel_args* args)
|
|||||||
BPrivate::CObjectDeleter<const char, status_t>
|
BPrivate::CObjectDeleter<const char, status_t>
|
||||||
acpiModulePutter(B_ACPI_MODULE_NAME, put_module);
|
acpiModulePutter(B_ACPI_MODULE_NAME, put_module);
|
||||||
|
|
||||||
// TODO: here ACPI needs to be used to properly set up the PCI IRQ
|
// switch to the APIC interrupt model before retrieving the irq routing
|
||||||
// routing.
|
// table as it will return different settings depending on the model
|
||||||
|
status = acpi_set_interrupt_model(acpiModule, ACPI_INTERRUPT_MODEL_APIC);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf("failed to put ACPI into APIC interrupt model, ignoring\n");
|
||||||
|
// don't abort, as the _PIC method is optional and as long as there
|
||||||
|
// aren't different routings based on it this is non-fatal
|
||||||
|
}
|
||||||
|
|
||||||
IRQRoutingTable table;
|
IRQRoutingTable table;
|
||||||
status = read_irq_routing_table(acpiModule, &table);
|
status = read_irq_routing_table(acpiModule, &table);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf("reading IRQ routing table failed, not configuring ioapic.\n");
|
dprintf("reading IRQ routing table failed, not configuring ioapic.\n");
|
||||||
|
acpi_set_interrupt_model(acpiModule, ACPI_INTERRUPT_MODEL_PIC);
|
||||||
|
// revert to PIC interrupt model just in case
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,6 +692,10 @@ ioapic_init(kernel_args* args)
|
|||||||
for (uint32 i = 0; i < 256; i++)
|
for (uint32 i = 0; i < 256; i++)
|
||||||
sIRQToIOAPICPin[i] = i;
|
sIRQToIOAPICPin[i] = i;
|
||||||
|
|
||||||
|
#ifdef TRACE_ARCH_INT
|
||||||
|
print_irq_routing_table(&table);
|
||||||
|
#endif
|
||||||
|
|
||||||
// configure io apic interrupts from pci routing table
|
// configure io apic interrupts from pci routing table
|
||||||
for (int i = 0; i < table.Count(); i++) {
|
for (int i = 0; i < table.Count(); i++) {
|
||||||
uint8 irq = 0;
|
uint8 irq = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user