From 0e48b234290f653e7afa77225337e5a62b5db6dd Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Wed, 29 Feb 2012 13:36:11 +0100 Subject: [PATCH] Refactored the interrupt code to make it cleaner and more flexible. Added support for hooking directly into an interrupt with your own interrupt handler. --- sortix/descriptor_tables.cpp | 63 +------- sortix/descriptor_tables.h | 65 +------- sortix/interrupt.cpp | 289 ++++++++++++++++++++++------------- sortix/interrupt.h | 121 +++++++++++---- sortix/kernel.cpp | 20 ++- sortix/x64/gdt.s | 3 - sortix/x64/interrupt.s | 5 + sortix/x86/gdt.asm | 1 - sortix/x86/interrupt.asm | 6 +- 9 files changed, 306 insertions(+), 267 deletions(-) diff --git a/sortix/descriptor_tables.cpp b/sortix/descriptor_tables.cpp index 4004cc9e..64f6d833 100644 --- a/sortix/descriptor_tables.cpp +++ b/sortix/descriptor_tables.cpp @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of Sortix. @@ -14,13 +14,13 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . descriptor_tables.cpp Initializes and handles the GDT, TSS and IDT. -******************************************************************************/ +*******************************************************************************/ #include "platform.h" #include @@ -183,57 +183,10 @@ namespace Sortix CPU::OutPortB(0xA1, 0x01); CPU::OutPortB(0x21, 0x0); CPU::OutPortB(0xA1, 0x0); + } - SetGate( 0, (addr_t) isr0 , 0x08, 0x8E); - SetGate( 1, (addr_t) isr1 , 0x08, 0x8E); - SetGate( 2, (addr_t) isr2 , 0x08, 0x8E); - SetGate( 3, (addr_t) isr3 , 0x08, 0x8E); - SetGate( 4, (addr_t) isr4 , 0x08, 0x8E); - SetGate( 5, (addr_t) isr5 , 0x08, 0x8E); - SetGate( 6, (addr_t) isr6 , 0x08, 0x8E); - SetGate( 7, (addr_t) isr7 , 0x08, 0x8E); - SetGate( 8, (addr_t) isr8 , 0x08, 0x8E); - SetGate( 9, (addr_t) isr9 , 0x08, 0x8E); - SetGate(10, (addr_t) isr10, 0x08, 0x8E); - SetGate(11, (addr_t) isr11, 0x08, 0x8E); - SetGate(12, (addr_t) isr12, 0x08, 0x8E); - SetGate(13, (addr_t) isr13, 0x08, 0x8E); - SetGate(14, (addr_t) isr14, 0x08, 0x8E); - SetGate(15, (addr_t) isr15, 0x08, 0x8E); - SetGate(16, (addr_t) isr16, 0x08, 0x8E); - SetGate(17, (addr_t) isr17, 0x08, 0x8E); - SetGate(18, (addr_t) isr18, 0x08, 0x8E); - SetGate(19, (addr_t) isr19, 0x08, 0x8E); - SetGate(20, (addr_t) isr20, 0x08, 0x8E); - SetGate(21, (addr_t) isr21, 0x08, 0x8E); - SetGate(22, (addr_t) isr22, 0x08, 0x8E); - SetGate(23, (addr_t) isr23, 0x08, 0x8E); - SetGate(24, (addr_t) isr24, 0x08, 0x8E); - SetGate(25, (addr_t) isr25, 0x08, 0x8E); - SetGate(26, (addr_t) isr26, 0x08, 0x8E); - SetGate(27, (addr_t) isr27, 0x08, 0x8E); - SetGate(28, (addr_t) isr28, 0x08, 0x8E); - SetGate(29, (addr_t) isr29, 0x08, 0x8E); - SetGate(30, (addr_t) isr30, 0x08, 0x8E); - SetGate(31, (addr_t) isr31, 0x08, 0x8E); - SetGate(32, (addr_t) irq0, 0x08, 0x8E); - SetGate(33, (addr_t) irq1, 0x08, 0x8E); - SetGate(34, (addr_t) irq2, 0x08, 0x8E); - SetGate(35, (addr_t) irq3, 0x08, 0x8E); - SetGate(36, (addr_t) irq4, 0x08, 0x8E); - SetGate(37, (addr_t) irq5, 0x08, 0x8E); - SetGate(38, (addr_t) irq6, 0x08, 0x8E); - SetGate(39, (addr_t) irq7, 0x08, 0x8E); - SetGate(40, (addr_t) irq8, 0x08, 0x8E); - SetGate(41, (addr_t) irq9, 0x08, 0x8E); - SetGate(42, (addr_t) irq10, 0x08, 0x8E); - SetGate(43, (addr_t) irq11, 0x08, 0x8E); - SetGate(44, (addr_t) irq12, 0x08, 0x8E); - SetGate(45, (addr_t) irq13, 0x08, 0x8E); - SetGate(46, (addr_t) irq14, 0x08, 0x8E); - SetGate(47, (addr_t) irq15, 0x08, 0x8E); - SetGate(128, (addr_t) syscall_handler, 0x08, 0x8E | 0x60); // System Calls - + void Flush() + { idt_flush((addr_t) &idt_ptr); } diff --git a/sortix/descriptor_tables.h b/sortix/descriptor_tables.h index 1be53acc..8155aeff 100644 --- a/sortix/descriptor_tables.h +++ b/sortix/descriptor_tables.h @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of Sortix. @@ -14,13 +14,13 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . - descriptor_tables.cpp + descriptor_tables.h Initializes and handles the GDT, TSS and IDT. -******************************************************************************/ +*******************************************************************************/ #ifndef SORTIX_DESCRIPTOR_TABLES_H #define SORTIX_DESCRIPTOR_TABLES_H @@ -125,7 +125,6 @@ namespace Sortix namespace IDT { - // A struct describing an interrupt gate. struct idt_entry32_struct { @@ -168,59 +167,9 @@ namespace Sortix void Init(); void SetGate(uint8_t num, addr_t base, uint16_t sel, uint8_t flags); + void Flush(); } } -// These extern directives let us access the addresses of our ASM ISR handlers. -extern "C" void isr0 (); -extern "C" void isr1 (); -extern "C" void isr2 (); -extern "C" void isr3 (); -extern "C" void isr4 (); -extern "C" void isr5 (); -extern "C" void isr6 (); -extern "C" void isr7 (); -extern "C" void isr8 (); -extern "C" void isr9 (); -extern "C" void isr10(); -extern "C" void isr11(); -extern "C" void isr12(); -extern "C" void isr13(); -extern "C" void isr14(); -extern "C" void isr15(); -extern "C" void isr16(); -extern "C" void isr17(); -extern "C" void isr18(); -extern "C" void isr19(); -extern "C" void isr20(); -extern "C" void isr21(); -extern "C" void isr22(); -extern "C" void isr23(); -extern "C" void isr24(); -extern "C" void isr25(); -extern "C" void isr26(); -extern "C" void isr27(); -extern "C" void isr28(); -extern "C" void isr29(); -extern "C" void isr30(); -extern "C" void isr31(); -extern "C" void isr128(); -extern "C" void irq0 (); -extern "C" void irq1 (); -extern "C" void irq2 (); -extern "C" void irq3 (); -extern "C" void irq4 (); -extern "C" void irq5 (); -extern "C" void irq6 (); -extern "C" void irq7 (); -extern "C" void irq8 (); -extern "C" void irq9 (); -extern "C" void irq10(); -extern "C" void irq11(); -extern "C" void irq12(); -extern "C" void irq13(); -extern "C" void irq14(); -extern "C" void irq15(); - #endif diff --git a/sortix/interrupt.cpp b/sortix/interrupt.cpp index fc54bb6f..a0c9e00b 100644 --- a/sortix/interrupt.cpp +++ b/sortix/interrupt.cpp @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of Sortix. @@ -14,18 +14,17 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . interrupt.cpp High level interrupt service routines and interrupt request handlers. -******************************************************************************/ +*******************************************************************************/ #include "platform.h" -#include "log.h" +#include "descriptor_tables.h" #include "interrupt.h" -#include "panic.h" #include "process.h" // Hack for SIGSEGV #include "sound.h" // Hack for SIGSEGV @@ -33,122 +32,200 @@ #include "syscall.h" // HACK FOR SIGSEGV #include "scheduler.h" // HACK FOR SIGSEGV -namespace Sortix +namespace Sortix { +void SysExit(int status); // HACK + +namespace Interrupt { + +const bool DEBUG_EXCEPTION = false; +const bool DEBUG_IRQ = false; +bool initialized; + +const size_t numknownexceptions = 20; +const char* exceptions[] = +{ "Divide by zero", "Debug", "Non maskable interrupt", "Breakpoint", + "Into detected overflow", "Out of bounds", "Invalid opcode", + "No coprocessor", "Double fault", "Coprocessor segment overrun", + "Bad TSS", "Segment not present", "Stack fault", + "General protection fault", "Page fault", "Unknown interrupt", + "Coprocessor fault", "Alignment check", "Machine check", + "SIMD Floating-Point" }; + +const size_t NUM_INTERRUPTS = 256UL; + +Handler interrupthandlers[NUM_INTERRUPTS]; +void* interrupthandlerptr[NUM_INTERRUPTS]; + +void Init() { - void SysExit(int status); // HACK + initialized = false; + IDT::Init(); - namespace Interrupt + for ( size_t i = 0; i < NUM_INTERRUPTS; i++ ) { - const bool DEBUG_EXCEPTION = false; - const bool DEBUG_IRQ = false; + interrupthandlers[i] = NULL; + interrupthandlerptr[i] = NULL; + } - size_t numknownexceptions = 20; - const char* exceptions[] = - { "Divide by zero", "Debug", "Non maskable interrupt", "Breakpoint", - "Into detected overflow", "Out of bounds", "Invalid opcode", - "No coprocessor", "Double fault", "Coprocessor segment overrun", - "Bad TSS", "Segment not present", "Stack fault", - "General protection fault", "Page fault", "Unknown interrupt", - "Coprocessor fault", "Alignment check", "Machine check", - "SIMD Floating-Point" }; + RegisterRawHandler(0, isr0, false); + RegisterRawHandler(1, isr1, false); + RegisterRawHandler(2, isr2, false); + RegisterRawHandler(3, isr3, false); + RegisterRawHandler(4, isr4, false); + RegisterRawHandler(5, isr5, false); + RegisterRawHandler(6, isr6, false); + RegisterRawHandler(7, isr7, false); + RegisterRawHandler(8, isr8, false); + RegisterRawHandler(9, isr9, false); + RegisterRawHandler(10, isr10, false); + RegisterRawHandler(11, isr11, false); + RegisterRawHandler(12, isr12, false); + RegisterRawHandler(13, isr13, false); + RegisterRawHandler(14, isr14, false); + RegisterRawHandler(15, isr15, false); + RegisterRawHandler(16, isr16, false); + RegisterRawHandler(17, isr17, false); + RegisterRawHandler(18, isr18, false); + RegisterRawHandler(19, isr19, false); + RegisterRawHandler(20, isr20, false); + RegisterRawHandler(21, isr21, false); + RegisterRawHandler(22, isr22, false); + RegisterRawHandler(23, isr23, false); + RegisterRawHandler(24, isr24, false); + RegisterRawHandler(25, isr25, false); + RegisterRawHandler(26, isr26, false); + RegisterRawHandler(27, isr27, false); + RegisterRawHandler(28, isr28, false); + RegisterRawHandler(29, isr29, false); + RegisterRawHandler(30, isr30, false); + RegisterRawHandler(31, isr31, false); + RegisterRawHandler(32, irq0, false); + RegisterRawHandler(33, irq1, false); + RegisterRawHandler(34, irq2, false); + RegisterRawHandler(35, irq3, false); + RegisterRawHandler(36, irq4, false); + RegisterRawHandler(37, irq5, false); + RegisterRawHandler(38, irq6, false); + RegisterRawHandler(39, irq7, false); + RegisterRawHandler(40, irq8, false); + RegisterRawHandler(41, irq9, false); + RegisterRawHandler(42, irq10, false); + RegisterRawHandler(43, irq11, false); + RegisterRawHandler(44, irq12, false); + RegisterRawHandler(45, irq13, false); + RegisterRawHandler(46, irq14, false); + RegisterRawHandler(47, irq15, false); - const size_t NUM_INTERRUPTS = 256UL; + for ( unsigned i = 48; i < 256; i++ ) + { + RegisterRawHandler(48, interrupt_handler_null, false); + } - Handler interrupthandlers[NUM_INTERRUPTS]; - void* interrupthandlerptr[NUM_INTERRUPTS]; + // TODO: Let the syscall.cpp code register this. + RegisterRawHandler(128, syscall_handler, true); - void Init() - { - for ( size_t i = 0; i < NUM_INTERRUPTS; i++ ) - { - interrupthandlers[i] = NULL; - interrupthandlerptr[i] = NULL; - } - } + IDT::Flush(); + initialized = true; - void RegisterHandler(uint8_t n, Interrupt::Handler handler, void* user) - { - interrupthandlers[n] = handler; - interrupthandlerptr[n] = user; - } + Interrupt::Enable(); +} - // This gets called from our ASM interrupt handler stub. - extern "C" void ISRHandler(Sortix::CPU::InterruptRegisters* regs) - { - if ( regs->int_no < 32 ) - { - const char* message = ( regs->int_no < numknownexceptions ) - ? exceptions[regs->int_no] : "Unknown"; +void RegisterHandler(uint8_t n, Interrupt::Handler handler, void* user) +{ + interrupthandlers[n] = handler; + interrupthandlerptr[n] = user; +} - if ( DEBUG_EXCEPTION ) { regs->LogRegisters(); Log::Print("\n"); } +// TODO: This function contains magic IDT-related values! +void RegisterRawHandler(uint8_t index, RawHandler handler, bool userspace) +{ + addr_t handlerentry = (addr_t) handler; + uint16_t sel = 0x08; + uint8_t flags = 0x8E; + if ( userspace ) { flags |= 0x60; } + IDT::SetGate(index, handlerentry, sel, flags); + if ( initialized ) { IDT::Flush(); } +} + +// This gets called from our ASM interrupt handler stub. +extern "C" void ISRHandler(Sortix::CPU::InterruptRegisters* regs) +{ + if ( regs->int_no < 32 ) + { + const char* message = ( regs->int_no < numknownexceptions ) + ? exceptions[regs->int_no] : "Unknown"; + + if ( DEBUG_EXCEPTION ) { regs->LogRegisters(); Log::Print("\n"); } #ifdef PLATFORM_X64 - addr_t ip = regs->rip; + addr_t ip = regs->rip; #else - addr_t ip = regs->eip; + addr_t ip = regs->eip; #endif - // Halt and catch fire if we are the kernel. - if ( (regs->cs & (0x4-1)) == 0 ) - { - PanicF("Unhandled CPU Exception id %zu '%s' at ip=0x%zx " - "(cr2=0x%p, err_code=0x%p)", regs->int_no, message, - ip, regs->cr2, regs->err_code); - } - - Log::Print("The current program has crashed and was terminated:\n"); - Log::PrintF("%s exception at ip=0x%zx (cr2=0x%p, err_code=0x%p)\n", - message, ip, regs->cr2, regs->err_code); - - Sound::Mute(); - - CurrentProcess()->Exit(139); - Scheduler::ProcessTerminated(regs); - - return; - } - - if ( interrupthandlers[regs->int_no] != NULL ) - { - void* user = interrupthandlerptr[regs->int_no]; - interrupthandlers[regs->int_no](regs, user); - } - } - - // This gets called from our ASM interrupt handler stub. - extern "C" void IRQHandler(Sortix::CPU::InterruptRegisters* regs) + // Halt and catch fire if we are the kernel. + if ( (regs->cs & (0x4-1)) == 0 ) { - // TODO! IRQ 7 and 15 might be spurious and might need to be ignored. - // See http://wiki.osdev.org/PIC for details (section Spurious IRQs). - if ( regs->int_no == 32 + 7 || regs->int_no == 32 + 15 ) { return; } - - if ( DEBUG_IRQ ) - { - Log::PrintF("IRQ%u ", regs->int_no-32); - regs->LogRegisters(); - Log::Print("\n"); - } - - // Send an EOI (end of interrupt) signal to the PICs. - - // Send reset signal to slave if this interrupt involved the slave. - if (regs->int_no >= 40) { CPU::OutPortB(0xA0, 0x20); } - - // Send reset signal to master. - CPU::OutPortB(0x20, 0x20); - - if ( interrupthandlers[regs->int_no] ) - { - void* user = interrupthandlerptr[regs->int_no]; - interrupthandlers[regs->int_no](regs, user); - } + PanicF("Unhandled CPU Exception id %zu '%s' at ip=0x%zx " + "(cr2=0x%p, err_code=0x%p)", regs->int_no, message, + ip, regs->cr2, regs->err_code); } - extern "C" void interrupt_handler(Sortix::CPU::InterruptRegisters* regs) - { - size_t int_no = regs->int_no; - if ( 32 <= int_no && int_no < 48 ) { IRQHandler(regs); } - else { ISRHandler(regs); } - } + Log::Print("The current program has crashed and was terminated:\n"); + Log::PrintF("%s exception at ip=0x%zx (cr2=0x%p, err_code=0x%p)\n", + message, ip, regs->cr2, regs->err_code); + + Sound::Mute(); + + CurrentProcess()->Exit(139); + Scheduler::ProcessTerminated(regs); + + return; + } + + if ( interrupthandlers[regs->int_no] != NULL ) + { + void* user = interrupthandlerptr[regs->int_no]; + interrupthandlers[regs->int_no](regs, user); } } + +// This gets called from our ASM interrupt handler stub. +extern "C" void IRQHandler(Sortix::CPU::InterruptRegisters* regs) +{ + // TODO! IRQ 7 and 15 might be spurious and might need to be ignored. + // See http://wiki.osdev.org/PIC for details (section Spurious IRQs). + if ( regs->int_no == 32 + 7 || regs->int_no == 32 + 15 ) { return; } + + if ( DEBUG_IRQ ) + { + Log::PrintF("IRQ%u ", regs->int_no-32); + regs->LogRegisters(); + Log::Print("\n"); + } + + // Send an EOI (end of interrupt) signal to the PICs. + + // Send reset signal to slave if this interrupt involved the slave. + if (regs->int_no >= 40) { CPU::OutPortB(0xA0, 0x20); } + + // Send reset signal to master. + CPU::OutPortB(0x20, 0x20); + + if ( interrupthandlers[regs->int_no] ) + { + void* user = interrupthandlerptr[regs->int_no]; + interrupthandlers[regs->int_no](regs, user); + } +} + +extern "C" void interrupt_handler(Sortix::CPU::InterruptRegisters* regs) +{ + size_t int_no = regs->int_no; + if ( 32 <= int_no && int_no < 48 ) { IRQHandler(regs); } + else { ISRHandler(regs); } +} + +} // namespace Interrupt +} // namespace Sortix + diff --git a/sortix/interrupt.h b/sortix/interrupt.h index 36fe1720..96568767 100644 --- a/sortix/interrupt.h +++ b/sortix/interrupt.h @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of Sortix. @@ -14,44 +14,101 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . interrupt.h High level interrupt service routines and interrupt request handlers. -******************************************************************************/ +*******************************************************************************/ -#ifndef SORTIX_ISR_H -#define SORTIX_ISR_H +#ifndef SORTIX_INTERRUPT_H +#define SORTIX_INTERRUPT_H -namespace Sortix -{ - namespace Interrupt - { - const unsigned IRQ0 = 32; - const unsigned IRQ1 = 33; - const unsigned IRQ2 = 34; - const unsigned IRQ3 = 35; - const unsigned IRQ4 = 36; - const unsigned IRQ5 = 37; - const unsigned IRQ6 = 38; - const unsigned IRQ7 = 39; - const unsigned IRQ8 = 30; - const unsigned IRQ9 = 41; - const unsigned IRQ10 = 42; - const unsigned IRQ11 = 43; - const unsigned IRQ12 = 44; - const unsigned IRQ13 = 45; - const unsigned IRQ14 = 46; - const unsigned IRQ15 = 47; +namespace Sortix { +namespace Interrupt { - typedef void (*Handler)(CPU::InterruptRegisters* regs, void* user); +const unsigned IRQ0 = 32; +const unsigned IRQ1 = 33; +const unsigned IRQ2 = 34; +const unsigned IRQ3 = 35; +const unsigned IRQ4 = 36; +const unsigned IRQ5 = 37; +const unsigned IRQ6 = 38; +const unsigned IRQ7 = 39; +const unsigned IRQ8 = 30; +const unsigned IRQ9 = 41; +const unsigned IRQ10 = 42; +const unsigned IRQ11 = 43; +const unsigned IRQ12 = 44; +const unsigned IRQ13 = 45; +const unsigned IRQ14 = 46; +const unsigned IRQ15 = 47; - void RegisterHandler(uint8_t n, Handler handler, void* user); +inline void Enable() { asm volatile("sti"); } +inline void Disable() { asm volatile("cli"); } - void Init(); - } -} +typedef void (*Handler)(CPU::InterruptRegisters* regs, void* user); +void RegisterHandler(uint8_t index, Handler handler, void* user); + +typedef void (*RawHandler)(void); +void RegisterRawHandler(uint8_t index, RawHandler handler, bool userspace); + +void Init(); + +} // namespace Interrupt +} // namespace Sortix + +extern "C" void isr0(); +extern "C" void isr1(); +extern "C" void isr2(); +extern "C" void isr3(); +extern "C" void isr4(); +extern "C" void isr5(); +extern "C" void isr6(); +extern "C" void isr7(); +extern "C" void isr8(); +extern "C" void isr9(); +extern "C" void isr10(); +extern "C" void isr11(); +extern "C" void isr12(); +extern "C" void isr13(); +extern "C" void isr14(); +extern "C" void isr15(); +extern "C" void isr16(); +extern "C" void isr17(); +extern "C" void isr18(); +extern "C" void isr19(); +extern "C" void isr20(); +extern "C" void isr21(); +extern "C" void isr22(); +extern "C" void isr23(); +extern "C" void isr24(); +extern "C" void isr25(); +extern "C" void isr26(); +extern "C" void isr27(); +extern "C" void isr28(); +extern "C" void isr29(); +extern "C" void isr30(); +extern "C" void isr31(); +extern "C" void isr128(); +extern "C" void irq0(); +extern "C" void irq1(); +extern "C" void irq2(); +extern "C" void irq3(); +extern "C" void irq4(); +extern "C" void irq5(); +extern "C" void irq6(); +extern "C" void irq7(); +extern "C" void irq8(); +extern "C" void irq9(); +extern "C" void irq10(); +extern "C" void irq11(); +extern "C" void irq12(); +extern "C" void irq13(); +extern "C" void irq14(); +extern "C" void irq15(); +extern "C" void interrupt_handler_null(); #endif + diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index 1bdd38ea..f9f6e32f 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of Sortix. @@ -14,13 +14,14 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . kernel.cpp - A common interface shared by all devices that can be printed text to. + The main kernel initialization routine. Configures hardware and starts an + initial process from the init ramdisk, allowing a full operating system. -******************************************************************************/ +*******************************************************************************/ #include "platform.h" #include @@ -205,7 +206,7 @@ namespace Sortix initrdsize = 0x280000; // 2 MiB 512 KiB #endif - Memory::RegisterInitRDSize(initrdsize);; + Memory::RegisterInitRDSize(initrdsize); // Initialize the paging and virtual memory. Memory::Init(BootInfo); @@ -213,12 +214,9 @@ namespace Sortix // Initialize the GDT and TSS structures. GDT::Init(); - // Initialize the interrupt handler table to zeroes. + // Initialize the interrupt handler table and enable interrupts. Interrupt::Init(); - // Initialize the interrupt descriptor tables (enabling interrupts). - IDT::Init(); - // Initialize the kernel heap. Maxsi::Memory::Init(); diff --git a/sortix/x64/gdt.s b/sortix/x64/gdt.s index 97d3c1e0..fedc0a5f 100644 --- a/sortix/x64/gdt.s +++ b/sortix/x64/gdt.s @@ -49,9 +49,6 @@ gdt_flush_postjmp: idt_flush: # Load the IDT pointer. lidt (%rdi) - - # Enable interrupts - sti ret .global tss_flush diff --git a/sortix/x64/interrupt.s b/sortix/x64/interrupt.s index 9c32c129..c7a30220 100644 --- a/sortix/x64/interrupt.s +++ b/sortix/x64/interrupt.s @@ -438,3 +438,8 @@ interrupt_handler_prepare: # Return to where we came from. iretq +.global interrupt_handler_null +.type interrupt_handler_null, @function +interrupt_handler_null: + iretq + diff --git a/sortix/x86/gdt.asm b/sortix/x86/gdt.asm index 940526a0..9062a8e7 100644 --- a/sortix/x86/gdt.asm +++ b/sortix/x86/gdt.asm @@ -25,7 +25,6 @@ gdt_flush: idt_flush: mov eax, [esp+4] ; Get the pointer to the IDT, passed as a parameter. lidt [eax] ; Load the IDT pointer. - sti ret [GLOBAL tss_flush] ; Allows our C code to call tss_flush(). diff --git a/sortix/x86/interrupt.asm b/sortix/x86/interrupt.asm index 3c8f4e00..1940d0da 100644 --- a/sortix/x86/interrupt.asm +++ b/sortix/x86/interrupt.asm @@ -157,5 +157,9 @@ irq_common_stub: ;sti iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP +global + +global interrupt_handler_null +interrupt_handler_null: + iret -