Support NMI sources. Any non maskable interrupt (NMI) will be marked as
unavailable for routing so that we don't end up configuring anything on them. I haven't seen these in actual use though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41530 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -103,6 +103,7 @@ struct ioapic {
|
|||||||
uint8 global_interrupt_base;
|
uint8 global_interrupt_base;
|
||||||
uint8 global_interrupt_last;
|
uint8 global_interrupt_last;
|
||||||
uint64 level_triggered_mask;
|
uint64 level_triggered_mask;
|
||||||
|
uint64 nmi_mask;
|
||||||
|
|
||||||
area_id register_area;
|
area_id register_area;
|
||||||
ioapic_registers* registers;
|
ioapic_registers* registers;
|
||||||
@@ -342,8 +343,10 @@ ioapic_initialize_ioapic(struct ioapic& ioapic, uint8 targetAPIC)
|
|||||||
// program the APIC ID
|
// program the APIC ID
|
||||||
ioapic_write_32(ioapic, IO_APIC_ID, ioapic.apic_id << IO_APIC_ID_SHIFT);
|
ioapic_write_32(ioapic, IO_APIC_ID, ioapic.apic_id << IO_APIC_ID_SHIFT);
|
||||||
|
|
||||||
// program the interrupt vectors of the io-apic
|
|
||||||
ioapic.level_triggered_mask = 0;
|
ioapic.level_triggered_mask = 0;
|
||||||
|
ioapic.nmi_mask = 0;
|
||||||
|
|
||||||
|
// program the interrupt vectors of the io-apic
|
||||||
uint8 gsi = ioapic.global_interrupt_base;
|
uint8 gsi = ioapic.global_interrupt_base;
|
||||||
for (uint8 i = 0; i <= ioapic.max_redirection_entry; i++, gsi++) {
|
for (uint8 i = 0; i <= ioapic.max_redirection_entry; i++, gsi++) {
|
||||||
// initialize everything to deliver to the boot CPU in physical mode
|
// initialize everything to deliver to the boot CPU in physical mode
|
||||||
@@ -510,6 +513,25 @@ acpi_configure_source_overrides(acpi_table_madt* madt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACPI_MADT_TYPE_NMI_SOURCE:
|
||||||
|
{
|
||||||
|
acpi_madt_nmi_source* info
|
||||||
|
= (acpi_madt_nmi_source*)apicEntry;
|
||||||
|
dprintf("found nmi source global irq %lu, flags 0x%04x\n",
|
||||||
|
(uint32)info->GlobalIrq, (uint16)info->IntiFlags);
|
||||||
|
|
||||||
|
struct ioapic* ioapic = find_ioapic(info->GlobalIrq);
|
||||||
|
if (ioapic == NULL) {
|
||||||
|
dprintf("nmi source for gsi that is not mapped to any "
|
||||||
|
" io-apic\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 pin = info->GlobalIrq - ioapic->global_interrupt_base;
|
||||||
|
ioapic->nmi_mask |= (uint64)1 << pin;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TRACE_IOAPIC
|
#ifdef TRACE_IOAPIC
|
||||||
case ACPI_MADT_TYPE_LOCAL_APIC:
|
case ACPI_MADT_TYPE_LOCAL_APIC:
|
||||||
{
|
{
|
||||||
@@ -521,16 +543,6 @@ acpi_configure_source_overrides(acpi_table_madt* madt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ACPI_MADT_TYPE_NMI_SOURCE:
|
|
||||||
{
|
|
||||||
// TODO: take these into account
|
|
||||||
acpi_madt_nmi_source* info
|
|
||||||
= (acpi_madt_nmi_source*)apicEntry;
|
|
||||||
dprintf("found nmi source global irq %lu, flags 0x%04x\n",
|
|
||||||
(uint32)info->GlobalIrq, (uint16)info->IntiFlags);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
|
case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
|
||||||
{
|
{
|
||||||
// TODO: take these into account, but at apic.cpp
|
// TODO: take these into account, but at apic.cpp
|
||||||
@@ -589,7 +601,12 @@ acpi_set_interrupt_model(acpi_module_info* acpiModule, uint32 interruptModel)
|
|||||||
bool
|
bool
|
||||||
ioapic_is_interrupt_available(int32 gsi)
|
ioapic_is_interrupt_available(int32 gsi)
|
||||||
{
|
{
|
||||||
return find_ioapic(gsi) != NULL;
|
struct ioapic* ioapic = find_ioapic(gsi);
|
||||||
|
if (ioapic == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8 pin = gsi - ioapic->global_interrupt_base;
|
||||||
|
return (ioapic->nmi_mask & ((uint64)1 << pin)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user