From 9de17be600220db91400c27772b19546284f470f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 15 Apr 2010 12:42:10 +0000 Subject: [PATCH] * Moved I/O APIC initialization to a later point, now the APCI and DPC modules can safely be used. * Since using the I/O APIC is disabled by default, I've removed the "return" that prevented its use when enabled. Let's see if it already does anything. * Adapted other arch_int.cpp with a bit of cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36290 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/int.h | 12 +++-- headers/private/kernel/int.h | 9 ++-- src/system/kernel/arch/arm/arch_int.cpp | 13 +++-- src/system/kernel/arch/m68k/arch_int.cpp | 15 ++++-- src/system/kernel/arch/mipsel/arch_int.cpp | 11 +++- src/system/kernel/arch/ppc/arch_int.cpp | 11 +++- src/system/kernel/arch/x86/arch_int.cpp | 63 +++++++++++++--------- src/system/kernel/int.cpp | 17 ++++-- src/system/kernel/main.cpp | 2 + 9 files changed, 104 insertions(+), 49 deletions(-) diff --git a/headers/private/kernel/arch/int.h b/headers/private/kernel/arch/int.h index a2d9d0ffa7..0af0039a6f 100644 --- a/headers/private/kernel/arch/int.h +++ b/headers/private/kernel/arch/int.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -15,19 +15,21 @@ #define B_LOW_ACTIVE_POLARITY 4 #define B_HIGH_ACTIVE_POLARITY 8 + #ifdef __cplusplus extern "C" { #endif struct kernel_args; -status_t arch_int_init(struct kernel_args *args); -status_t arch_int_init_post_vm(struct kernel_args *args); -status_t arch_int_init_post_device_manager(struct kernel_args *args); +status_t arch_int_init(struct kernel_args* args); +status_t arch_int_init_post_vm(struct kernel_args* args); +status_t arch_int_init_io(kernel_args* args); +status_t arch_int_init_post_device_manager(struct kernel_args* args); void arch_int_enable_interrupts(void); int arch_int_disable_interrupts(void); -void arch_int_restore_interrupts(int oldstate); +void arch_int_restore_interrupts(int oldState); void arch_int_enable_io_interrupt(int irq); void arch_int_disable_io_interrupt(int irq); void arch_int_configure_io_interrupt(int irq, uint32 config); diff --git a/headers/private/kernel/int.h b/headers/private/kernel/int.h index 7c6daa7a14..c43ed84054 100644 --- a/headers/private/kernel/int.h +++ b/headers/private/kernel/int.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -23,9 +23,10 @@ struct kernel_args; extern "C" { #endif -status_t int_init(struct kernel_args *args); -status_t int_init_post_vm(struct kernel_args *args); -status_t int_init_post_device_manager(struct kernel_args *args); +status_t int_init(struct kernel_args* args); +status_t int_init_post_vm(struct kernel_args* args); +status_t int_init_io(kernel_args* args); +status_t int_init_post_device_manager(struct kernel_args* args); int int_io_interrupt_handler(int vector, bool levelTriggered); bool interrupts_enabled(void); diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp index 10e7502f62..0bd3333100 100644 --- a/src/system/kernel/arch/arm/arch_int.cpp +++ b/src/system/kernel/arch/arm/arch_int.cpp @@ -1,21 +1,19 @@ /* - * Copyright 2003-2006, Haiku Inc. All rights reserved. + * Copyright 2003-2010, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler * Ingo Weinhold * François Revol - * Distributed under the terms of the MIT License. - * * * Copyright 2001, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. */ + #include -//#include #include #include #include @@ -112,6 +110,7 @@ print_iframe(struct iframe *frame) #warning ARM WRITEME } + status_t arch_int_init(kernel_args *args) { @@ -145,6 +144,12 @@ arch_int_init_post_vm(kernel_args *args) } +status_t +arch_int_init_io(kernel_args* args) +{ + return B_OK; +} + status_t arch_int_init_post_device_manager(struct kernel_args *args) diff --git a/src/system/kernel/arch/m68k/arch_int.cpp b/src/system/kernel/arch/m68k/arch_int.cpp index 466443c7fc..81e9365f39 100644 --- a/src/system/kernel/arch/m68k/arch_int.cpp +++ b/src/system/kernel/arch/m68k/arch_int.cpp @@ -1,18 +1,17 @@ /* - * Copyright 2003-2009, Haiku Inc. All rights reserved. + * Copyright 2003-2010, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler * Ingo Weinhold * François Revol - * Distributed under the terms of the MIT License. - * * * Copyright 2001, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. */ + #include #include @@ -121,6 +120,7 @@ print_iframe(struct iframe *frame) #endif } + static addr_t fault_address(struct iframe *iframe) { @@ -145,6 +145,7 @@ fault_address(struct iframe *iframe) } } + static bool fault_was_write(struct iframe *iframe) { @@ -162,6 +163,7 @@ fault_was_write(struct iframe *iframe) } } + extern "C" void m68k_exception_entry(struct iframe *iframe); void m68k_exception_entry(struct iframe *iframe) @@ -347,6 +349,13 @@ arch_int_init_post_vm(kernel_args *args) } +status_t +arch_int_init_io(kernel_args* args) +{ + return B_OK; +} + + #if 0 /* PIC modules */ template struct Module : DoublyLinkedListLinkImpl > { diff --git a/src/system/kernel/arch/mipsel/arch_int.cpp b/src/system/kernel/arch/mipsel/arch_int.cpp index ef0c7f8c99..b4641a12dd 100644 --- a/src/system/kernel/arch/mipsel/arch_int.cpp +++ b/src/system/kernel/arch/mipsel/arch_int.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009, Haiku Inc. All rights reserved. + * Copyright 2003-2010, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -11,9 +11,9 @@ * Distributed under the terms of the NewOS License. */ + #include -//#include #include #include #include @@ -79,6 +79,13 @@ arch_int_init_post_vm(kernel_args* args) } +status_t +arch_int_init_io(kernel_args* args) +{ + return B_OK; +} + + status_t arch_int_init_post_device_manager(struct kernel_args* args) { diff --git a/src/system/kernel/arch/ppc/arch_int.cpp b/src/system/kernel/arch/ppc/arch_int.cpp index 0c67220e00..a9e9f4be96 100644 --- a/src/system/kernel/arch/ppc/arch_int.cpp +++ b/src/system/kernel/arch/ppc/arch_int.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009, Haiku Inc. All rights reserved. + * Copyright 2003-2010, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ * Distributed under the terms of the NewOS License. */ + #include #include @@ -28,6 +29,7 @@ #include + // defined in arch_exceptions.S extern int __irqvec_start; extern int __irqvec_end; @@ -313,6 +315,13 @@ arch_int_init_post_vm(kernel_args *args) } +status_t +arch_int_init_io(kernel_args* args) +{ + return B_OK; +} + + template struct Module : DoublyLinkedListLinkImpl > { Module(ModuleInfo *module) diff --git a/src/system/kernel/arch/x86/arch_int.cpp b/src/system/kernel/arch/x86/arch_int.cpp index 0e3a34fa6b..2cc09b5658 100644 --- a/src/system/kernel/arch/x86/arch_int.cpp +++ b/src/system/kernel/arch/x86/arch_int.cpp @@ -1,7 +1,7 @@ /* * Copyright 2010, Clemens Zeidler, haiku@clemens-zeidler.de. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -538,7 +538,22 @@ ioapic_configure_io_interrupt(int32 num, uint32 config) static void -ioapic_init(kernel_args *args) +ioapic_map(kernel_args* args) +{ + // map in the ioapic + sIOAPIC = (ioapic *)args->arch_args.ioapic; + if (vm_map_physical_memory(B_SYSTEM_TEAM, "ioapic", (void**)&sIOAPIC, + B_EXACT_ADDRESS, B_PAGE_SIZE, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, + args->arch_args.ioapic_phys, true) < 0) { + panic("mapping the ioapic failed"); + return; + } +} + + +static void +ioapic_init(kernel_args* args) { static const interrupt_controller ioapicController = { "82093AA IOAPIC", @@ -549,10 +564,6 @@ ioapic_init(kernel_args *args) &ioapic_end_of_interrupt }; - // always init the local apic as it can be used for timers even if we - // don't end up using the io apic - apic_init(args); - if (args->arch_args.apic == NULL) { dprintf("no local apic available\n"); return; @@ -569,8 +580,11 @@ ioapic_init(kernel_args *args) return; } - // TODO: remove when the PCI IRQ routing through ACPI is available below - return; + uint32 version = ioapic_read_32(IO_APIC_VERSION); + if (version == 0xffffffff) { + dprintf("ioapic seems inaccessible, not using it\n"); + return; + } // load acpi module status_t status; @@ -582,6 +596,7 @@ ioapic_init(kernel_args *args) } BPrivate::CObjectDeleter acpiModulePutter(B_ACPI_MODULE_NAME, put_module); + // load pci module pci_module_info* pciModule; status = get_module(B_PCI_MODULE_NAME, (module_info**)&pciModule); @@ -592,22 +607,6 @@ ioapic_init(kernel_args *args) CObjectDeleter pciModulePutter(B_PCI_MODULE_NAME, put_module); - // map in the ioapic - sIOAPIC = (ioapic *)args->arch_args.ioapic; - if (vm_map_physical_memory(B_SYSTEM_TEAM, "ioapic", (void**)&sIOAPIC, - B_EXACT_ADDRESS, B_PAGE_SIZE, - B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, - args->arch_args.ioapic_phys, true) < 0) { - panic("mapping the ioapic failed"); - return; - } - - uint32 version = ioapic_read_32(IO_APIC_VERSION); - if (version == 0xffffffff) { - dprintf("ioapic seems inaccessible, not using it\n"); - return; - } - sLevelTriggeredInterrupts = 0; sIOAPICMaxRedirectionEntry = ((version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT) @@ -1346,7 +1345,13 @@ arch_int_init(struct kernel_args *args) status_t arch_int_init_post_vm(struct kernel_args *args) { - ioapic_init(args); + // Always init the local apic as it can be used for timers even if we + // don't end up using the io apic + apic_init(args); + + // We need to map in the I/O APIC here, since we would lose the already + // wired mapping before arch_int_init_io() is called. + ioapic_map(args); // create IDT area for the boot CPU area_id area = create_area("idt", (void**)&sIDTs[0], B_EXACT_ADDRESS, @@ -1378,6 +1383,14 @@ arch_int_init_post_vm(struct kernel_args *args) } +status_t +arch_int_init_io(kernel_args* args) +{ + ioapic_init(args); + return B_OK; +} + + status_t arch_int_init_post_device_manager(struct kernel_args *args) { diff --git a/src/system/kernel/int.cpp b/src/system/kernel/int.cpp index 90c71eea09..8ac9d6a90c 100644 --- a/src/system/kernel/int.cpp +++ b/src/system/kernel/int.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -120,7 +120,7 @@ interrupts_enabled(void) status_t -int_init(kernel_args *args) +int_init(kernel_args* args) { TRACE(("init_int_handlers: entry\n")); @@ -129,7 +129,7 @@ int_init(kernel_args *args) status_t -int_init_post_vm(kernel_args *args) +int_init_post_vm(kernel_args* args) { int i; @@ -157,7 +157,14 @@ int_init_post_vm(kernel_args *args) status_t -int_init_post_device_manager(kernel_args *args) +int_init_io(kernel_args* args) +{ + return arch_int_init_io(args); +} + + +status_t +int_init_post_device_manager(kernel_args* args) { arch_debug_install_interrupt_handlers(); @@ -172,7 +179,7 @@ int int_io_interrupt_handler(int vector, bool levelTriggered) { int status = B_UNHANDLED_INTERRUPT; - struct io_handler *io; + struct io_handler* io; bool handled = false; if (!sVectors[vector].no_lock_vector) diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index c21bfd3ea6..e2fe9f2ef1 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -171,6 +171,8 @@ _start(kernel_args *bootKernelArgs, int currentCPU) kernel_daemon_init(); arch_platform_init_post_thread(&sKernelArgs); + TRACE("init I/O interrupts\n"); + int_init_io(&sKernelArgs); TRACE("init VM threads\n"); vm_init_post_thread(&sKernelArgs); low_resource_manager_init_post_thread();