* Move redirection entry configuration into a separate function and allow to
specify the delivery mode. * Use that function from ioapic_configure_io_interrupt() and use it when configuring NMI sources to actually set the entries to NMI. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41531 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -192,6 +192,35 @@ ioapic_write_64(struct ioapic& ioapic, uint8 registerSelect, uint64 value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ioapic_configure_pin(struct ioapic& ioapic, uint8 pin, uint8 vector,
|
||||||
|
uint8 triggerPolarity, uint8 deliveryMode)
|
||||||
|
{
|
||||||
|
uint64 entry = ioapic_read_64(ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
|
||||||
|
entry &= ~((1 << IO_APIC_TRIGGER_MODE_SHIFT)
|
||||||
|
| (1 << IO_APIC_PIN_POLARITY_SHIFT)
|
||||||
|
| (IO_APIC_INTERRUPT_VECTOR_MASK << IO_APIC_INTERRUPT_VECTOR_SHIFT))
|
||||||
|
| (IO_APIC_DELIVERY_MODE_MASK << IO_APIC_DELIVERY_MODE_SHIFT);
|
||||||
|
|
||||||
|
if (triggerPolarity & B_LEVEL_TRIGGERED) {
|
||||||
|
entry |= (IO_APIC_TRIGGER_MODE_LEVEL << IO_APIC_TRIGGER_MODE_SHIFT);
|
||||||
|
ioapic.level_triggered_mask |= ((uint64)1 << pin);
|
||||||
|
} else {
|
||||||
|
entry |= (IO_APIC_TRIGGER_MODE_EDGE << IO_APIC_TRIGGER_MODE_SHIFT);
|
||||||
|
ioapic.level_triggered_mask &= ~((uint64)1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerPolarity & B_LOW_ACTIVE_POLARITY)
|
||||||
|
entry |= (IO_APIC_PIN_POLARITY_LOW_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT);
|
||||||
|
else
|
||||||
|
entry |= (IO_APIC_PIN_POLARITY_HIGH_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT);
|
||||||
|
|
||||||
|
entry |= (uint64)deliveryMode << IO_APIC_DELIVERY_MODE_SHIFT;
|
||||||
|
entry |= (vector + ARCH_INTERRUPT_BASE) << IO_APIC_INTERRUPT_VECTOR_SHIFT;
|
||||||
|
ioapic_write_64(ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ioapic_is_spurious_interrupt(int32 gsi)
|
ioapic_is_spurious_interrupt(int32 gsi)
|
||||||
{
|
{
|
||||||
@@ -273,26 +302,8 @@ ioapic_configure_io_interrupt(int32 gsi, uint32 config)
|
|||||||
TRACE(("ioapic_configure_io_interrupt: gsi %ld -> io-apic %u pin %u; "
|
TRACE(("ioapic_configure_io_interrupt: gsi %ld -> io-apic %u pin %u; "
|
||||||
"config 0x%08lx\n", gsi, ioapic->number, pin, config));
|
"config 0x%08lx\n", gsi, ioapic->number, pin, config));
|
||||||
|
|
||||||
uint64 entry = ioapic_read_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2);
|
ioapic_configure_pin(*ioapic, pin, gsi, config,
|
||||||
entry &= ~((1 << IO_APIC_TRIGGER_MODE_SHIFT)
|
IO_APIC_DELIVERY_MODE_FIXED);
|
||||||
| (1 << IO_APIC_PIN_POLARITY_SHIFT)
|
|
||||||
| (IO_APIC_INTERRUPT_VECTOR_MASK << IO_APIC_INTERRUPT_VECTOR_SHIFT));
|
|
||||||
|
|
||||||
if (config & B_LEVEL_TRIGGERED) {
|
|
||||||
entry |= (IO_APIC_TRIGGER_MODE_LEVEL << IO_APIC_TRIGGER_MODE_SHIFT);
|
|
||||||
ioapic->level_triggered_mask |= ((uint64)1 << pin);
|
|
||||||
} else {
|
|
||||||
entry |= (IO_APIC_TRIGGER_MODE_EDGE << IO_APIC_TRIGGER_MODE_SHIFT);
|
|
||||||
ioapic->level_triggered_mask &= ~((uint64)1 << pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config & B_LOW_ACTIVE_POLARITY)
|
|
||||||
entry |= (IO_APIC_PIN_POLARITY_LOW_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT);
|
|
||||||
else
|
|
||||||
entry |= (IO_APIC_PIN_POLARITY_HIGH_ACTIVE << IO_APIC_PIN_POLARITY_SHIFT);
|
|
||||||
|
|
||||||
entry |= (gsi + ARCH_INTERRUPT_BASE) << IO_APIC_INTERRUPT_VECTOR_SHIFT;
|
|
||||||
ioapic_write_64(*ioapic, IO_APIC_REDIRECTION_TABLE + pin * 2, entry, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -450,6 +461,40 @@ acpi_enumerate_ioapics(acpi_table_madt* madt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32
|
||||||
|
acpi_madt_convert_inti_flags(uint16 flags)
|
||||||
|
{
|
||||||
|
uint32 config = 0;
|
||||||
|
switch (flags & ACPI_MADT_POLARITY_MASK) {
|
||||||
|
case ACPI_MADT_POLARITY_ACTIVE_LOW:
|
||||||
|
config = B_LOW_ACTIVE_POLARITY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintf("invalid polarity in inti flags\n");
|
||||||
|
// fall through and assume active high
|
||||||
|
case ACPI_MADT_POLARITY_ACTIVE_HIGH:
|
||||||
|
case ACPI_MADT_POLARITY_CONFORMS:
|
||||||
|
config = B_HIGH_ACTIVE_POLARITY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flags & ACPI_MADT_TRIGGER_MASK) {
|
||||||
|
case ACPI_MADT_TRIGGER_LEVEL:
|
||||||
|
config |= B_LEVEL_TRIGGERED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintf("invalid trigger mode in source override\n");
|
||||||
|
// fall through and assume edge triggered
|
||||||
|
case ACPI_MADT_TRIGGER_CONFORMS:
|
||||||
|
case ACPI_MADT_TRIGGER_EDGE:
|
||||||
|
config |= B_EDGE_TRIGGERED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acpi_configure_source_overrides(acpi_table_madt* madt)
|
acpi_configure_source_overrides(acpi_table_madt* madt)
|
||||||
{
|
{
|
||||||
@@ -482,33 +527,7 @@ acpi_configure_source_overrides(acpi_table_madt* madt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configure non-standard polarity/trigger modes
|
// configure non-standard polarity/trigger modes
|
||||||
uint32 config = 0;
|
uint32 config = acpi_madt_convert_inti_flags(info->IntiFlags);
|
||||||
switch (info->IntiFlags & ACPI_MADT_POLARITY_MASK) {
|
|
||||||
case ACPI_MADT_POLARITY_ACTIVE_LOW:
|
|
||||||
config = B_LOW_ACTIVE_POLARITY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dprintf("invalid polarity in source override\n");
|
|
||||||
// fall through and assume active high
|
|
||||||
case ACPI_MADT_POLARITY_ACTIVE_HIGH:
|
|
||||||
case ACPI_MADT_POLARITY_CONFORMS:
|
|
||||||
config = B_HIGH_ACTIVE_POLARITY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (info->IntiFlags & ACPI_MADT_TRIGGER_MASK) {
|
|
||||||
case ACPI_MADT_TRIGGER_LEVEL:
|
|
||||||
config |= B_LEVEL_TRIGGERED;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dprintf("invalid trigger mode in source override\n");
|
|
||||||
// fall through and assume edge triggered
|
|
||||||
case ACPI_MADT_TRIGGER_CONFORMS:
|
|
||||||
case ACPI_MADT_TRIGGER_EDGE:
|
|
||||||
config |= B_EDGE_TRIGGERED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioapic_configure_io_interrupt(info->GlobalIrq, config);
|
ioapic_configure_io_interrupt(info->GlobalIrq, config);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -529,6 +548,10 @@ acpi_configure_source_overrides(acpi_table_madt* madt)
|
|||||||
|
|
||||||
uint8 pin = info->GlobalIrq - ioapic->global_interrupt_base;
|
uint8 pin = info->GlobalIrq - ioapic->global_interrupt_base;
|
||||||
ioapic->nmi_mask |= (uint64)1 << pin;
|
ioapic->nmi_mask |= (uint64)1 << pin;
|
||||||
|
|
||||||
|
uint32 config = acpi_madt_convert_inti_flags(info->IntiFlags);
|
||||||
|
ioapic_configure_pin(*ioapic, pin, info->GlobalIrq, config,
|
||||||
|
IO_APIC_DELIVERY_MODE_NMI);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user