diff --git a/headers/private/kernel/arch/x86/ioapic.h b/headers/private/kernel/arch/x86/ioapic.h index a48e215ea7..d08ebf8ad4 100644 --- a/headers/private/kernel/arch/x86/ioapic.h +++ b/headers/private/kernel/arch/x86/ioapic.h @@ -11,6 +11,7 @@ struct kernel_args; bool ioapic_is_interrupt_available(int32 gsi); -void ioapic_init(kernel_args* args); +void ioapic_preinit(kernel_args* args); +void ioapic_init(); #endif // _KERNEL_ARCH_x86_IOAPIC_H diff --git a/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp b/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp index 999ba37a6d..0941d15d23 100644 --- a/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp +++ b/src/add-ons/kernel/busses/pci/x86/X86PCIController.cpp @@ -6,6 +6,8 @@ #include "X86PCIController.h" +#include + #include #include @@ -152,11 +154,18 @@ X86PCIController::WriteIrq(uint8 bus, uint8 device, uint8 function, status_t X86PCIController::GetRange(uint32 index, pci_resource_range* range) { - return B_BAD_INDEX; } +status_t +X86PCIController::Finalize() +{ + ioapic_init(); + return B_OK; +} + + //#pragma mark - X86PCIControllerMeth1 @@ -238,13 +247,6 @@ status_t X86PCIControllerMeth1::GetMaxBusDevices(int32& count) } -status_t -X86PCIControllerMeth1::Finalize() -{ - return B_OK; -} - - //#pragma mark - X86PCIControllerMeth2 @@ -332,13 +334,6 @@ status_t X86PCIControllerMeth2::GetMaxBusDevices(int32& count) } -status_t -X86PCIControllerMeth2::Finalize() -{ - return B_OK; -} - - //#pragma mark - X86PCIControllerMethPcie @@ -410,11 +405,3 @@ X86PCIControllerMethPcie::GetRange(uint32 index, pci_resource_range* range) { return fECAMPCIController.GetRange(index, range); } - - -status_t -X86PCIControllerMethPcie::Finalize() -{ - // No need to call fECAMPCIController.Finalize(): IRQ routing is handled by IOAPIC on x86. - return B_OK; -} diff --git a/src/add-ons/kernel/busses/pci/x86/X86PCIController.h b/src/add-ons/kernel/busses/pci/x86/X86PCIController.h index b9d06a03b3..d6a80a73c3 100644 --- a/src/add-ons/kernel/busses/pci/x86/X86PCIController.h +++ b/src/add-ons/kernel/busses/pci/x86/X86PCIController.h @@ -41,7 +41,7 @@ public: virtual status_t GetRange(uint32 index, pci_resource_range* range); - virtual status_t Finalize() = 0; + virtual status_t Finalize() final; status_t ReadIrq( uint8 bus, uint8 device, uint8 function, @@ -78,8 +78,6 @@ public: uint16 offset, uint8 size, uint32 value) override; status_t GetMaxBusDevices(int32& count) override; - - status_t Finalize() override; }; @@ -98,8 +96,6 @@ public: uint16 offset, uint8 size, uint32 value) final; status_t GetMaxBusDevices(int32& count) final; - - status_t Finalize() final; }; @@ -121,8 +117,6 @@ public: status_t GetRange(uint32 index, pci_resource_range* range) final; - status_t Finalize() final; - private: ECAMPCIControllerACPI fECAMPCIController; }; diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index 025d431dd6..9281a5e71a 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -467,7 +467,7 @@ status_t arch_int_init_io(kernel_args* args) { msi_init(args); - ioapic_init(args); + ioapic_preinit(args); return B_OK; } diff --git a/src/system/kernel/arch/x86/ioapic.cpp b/src/system/kernel/arch/x86/ioapic.cpp index fff4fa7d63..bfba9c0eb1 100644 --- a/src/system/kernel/arch/x86/ioapic.cpp +++ b/src/system/kernel/arch/x86/ioapic.cpp @@ -108,6 +108,7 @@ struct ioapic { }; +static int32 sIOAPICPhys = 0; static ioapic* sIOAPICs = NULL; static int32 sSourceOverrides[ISA_INTERRUPT_COUNT]; @@ -670,7 +671,16 @@ ioapic_is_interrupt_available(int32 gsi) void -ioapic_init(kernel_args* args) +ioapic_preinit(kernel_args* args) +{ + sIOAPICPhys = args->arch_args.ioapic_phys; + + // The real IO-APIC initialization occurs after PCI initialization. +} + + +void +ioapic_init() { static const interrupt_controller ioapicController = { "82093AA IOAPIC", @@ -683,10 +693,10 @@ ioapic_init(kernel_args* args) &ioapic_assign_interrupt_to_cpu, }; - if (args->arch_args.apic == NULL) + if (!apic_available()) return; - if (args->arch_args.ioapic_phys == 0) { + if (sIOAPICPhys == 0) { dprintf("no io-apics available, not using io-apics for interrupt " "routing\n"); return; @@ -698,12 +708,12 @@ ioapic_init(kernel_args* args) return; } - // load acpi module + // load ACPI module status_t status; acpi_module_info* acpiModule; status = get_module(B_ACPI_MODULE_NAME, (module_info**)&acpiModule); if (status != B_OK) { - dprintf("acpi module not available, not configuring io-apics\n"); + dprintf("ACPI module not available, not configuring io-apics\n"); return; } BPrivate::CObjectDeleter @@ -743,7 +753,7 @@ ioapic_init(kernel_args* args) } // use the boot CPU as the target for all interrupts - uint8 targetAPIC = args->arch_args.cpu_apic_id[0]; + uint8 targetAPIC = x86_get_cpu_apic_id(0); struct ioapic* current = sIOAPICs; while (current != NULL) {