Added support for 64-bit interrupts.
This commit is contained in:
parent
f0ec4ffacc
commit
f460c4abec
|
@ -167,85 +167,84 @@ namespace Sortix
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_X86
|
|
||||||
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
||||||
idt_ptr.base = (uint32_t)&idt_entries;
|
idt_ptr.base = (addr_t) &idt_entries;
|
||||||
|
|
||||||
Memory::Set(&idt_entries, 0, sizeof(idt_entry_t)*256);
|
Memory::Set(&idt_entries, 0, sizeof(idt_entry_t)*256);
|
||||||
|
|
||||||
// Remap the irq table.
|
// Remap the irq table.
|
||||||
X86::OutPortB(0x20, 0x11);
|
CPU::OutPortB(0x20, 0x11);
|
||||||
X86::OutPortB(0xA0, 0x11);
|
CPU::OutPortB(0xA0, 0x11);
|
||||||
X86::OutPortB(0x21, 0x20);
|
CPU::OutPortB(0x21, 0x20);
|
||||||
X86::OutPortB(0xA1, 0x28);
|
CPU::OutPortB(0xA1, 0x28);
|
||||||
X86::OutPortB(0x21, 0x04);
|
CPU::OutPortB(0x21, 0x04);
|
||||||
X86::OutPortB(0xA1, 0x02);
|
CPU::OutPortB(0xA1, 0x02);
|
||||||
X86::OutPortB(0x21, 0x01);
|
CPU::OutPortB(0x21, 0x01);
|
||||||
X86::OutPortB(0xA1, 0x01);
|
CPU::OutPortB(0xA1, 0x01);
|
||||||
X86::OutPortB(0x21, 0x0);
|
CPU::OutPortB(0x21, 0x0);
|
||||||
X86::OutPortB(0xA1, 0x0);
|
CPU::OutPortB(0xA1, 0x0);
|
||||||
|
|
||||||
SetGate( 0, (uint32_t) isr0 , 0x08, 0x8E);
|
SetGate( 0, (addr_t) isr0 , 0x08, 0x8E);
|
||||||
SetGate( 1, (uint32_t) isr1 , 0x08, 0x8E);
|
SetGate( 1, (addr_t) isr1 , 0x08, 0x8E);
|
||||||
SetGate( 2, (uint32_t) isr2 , 0x08, 0x8E);
|
SetGate( 2, (addr_t) isr2 , 0x08, 0x8E);
|
||||||
SetGate( 3, (uint32_t) isr3 , 0x08, 0x8E);
|
SetGate( 3, (addr_t) isr3 , 0x08, 0x8E);
|
||||||
SetGate( 4, (uint32_t) isr4 , 0x08, 0x8E);
|
SetGate( 4, (addr_t) isr4 , 0x08, 0x8E);
|
||||||
SetGate( 5, (uint32_t) isr5 , 0x08, 0x8E);
|
SetGate( 5, (addr_t) isr5 , 0x08, 0x8E);
|
||||||
SetGate( 6, (uint32_t) isr6 , 0x08, 0x8E);
|
SetGate( 6, (addr_t) isr6 , 0x08, 0x8E);
|
||||||
SetGate( 7, (uint32_t) isr7 , 0x08, 0x8E);
|
SetGate( 7, (addr_t) isr7 , 0x08, 0x8E);
|
||||||
SetGate( 8, (uint32_t) isr8 , 0x08, 0x8E);
|
SetGate( 8, (addr_t) isr8 , 0x08, 0x8E);
|
||||||
SetGate( 9, (uint32_t) isr9 , 0x08, 0x8E);
|
SetGate( 9, (addr_t) isr9 , 0x08, 0x8E);
|
||||||
SetGate(10, (uint32_t) isr10, 0x08, 0x8E);
|
SetGate(10, (addr_t) isr10, 0x08, 0x8E);
|
||||||
SetGate(11, (uint32_t) isr11, 0x08, 0x8E);
|
SetGate(11, (addr_t) isr11, 0x08, 0x8E);
|
||||||
SetGate(12, (uint32_t) isr12, 0x08, 0x8E);
|
SetGate(12, (addr_t) isr12, 0x08, 0x8E);
|
||||||
SetGate(13, (uint32_t) isr13, 0x08, 0x8E);
|
SetGate(13, (addr_t) isr13, 0x08, 0x8E);
|
||||||
SetGate(14, (uint32_t) isr14, 0x08, 0x8E);
|
SetGate(14, (addr_t) isr14, 0x08, 0x8E);
|
||||||
SetGate(15, (uint32_t) isr15, 0x08, 0x8E);
|
SetGate(15, (addr_t) isr15, 0x08, 0x8E);
|
||||||
SetGate(16, (uint32_t) isr16, 0x08, 0x8E);
|
SetGate(16, (addr_t) isr16, 0x08, 0x8E);
|
||||||
SetGate(17, (uint32_t) isr17, 0x08, 0x8E);
|
SetGate(17, (addr_t) isr17, 0x08, 0x8E);
|
||||||
SetGate(18, (uint32_t) isr18, 0x08, 0x8E);
|
SetGate(18, (addr_t) isr18, 0x08, 0x8E);
|
||||||
SetGate(19, (uint32_t) isr19, 0x08, 0x8E);
|
SetGate(19, (addr_t) isr19, 0x08, 0x8E);
|
||||||
SetGate(20, (uint32_t) isr20, 0x08, 0x8E);
|
SetGate(20, (addr_t) isr20, 0x08, 0x8E);
|
||||||
SetGate(21, (uint32_t) isr21, 0x08, 0x8E);
|
SetGate(21, (addr_t) isr21, 0x08, 0x8E);
|
||||||
SetGate(22, (uint32_t) isr22, 0x08, 0x8E);
|
SetGate(22, (addr_t) isr22, 0x08, 0x8E);
|
||||||
SetGate(23, (uint32_t) isr23, 0x08, 0x8E);
|
SetGate(23, (addr_t) isr23, 0x08, 0x8E);
|
||||||
SetGate(24, (uint32_t) isr24, 0x08, 0x8E);
|
SetGate(24, (addr_t) isr24, 0x08, 0x8E);
|
||||||
SetGate(25, (uint32_t) isr25, 0x08, 0x8E);
|
SetGate(25, (addr_t) isr25, 0x08, 0x8E);
|
||||||
SetGate(26, (uint32_t) isr26, 0x08, 0x8E);
|
SetGate(26, (addr_t) isr26, 0x08, 0x8E);
|
||||||
SetGate(27, (uint32_t) isr27, 0x08, 0x8E);
|
SetGate(27, (addr_t) isr27, 0x08, 0x8E);
|
||||||
SetGate(28, (uint32_t) isr28, 0x08, 0x8E);
|
SetGate(28, (addr_t) isr28, 0x08, 0x8E);
|
||||||
SetGate(29, (uint32_t) isr29, 0x08, 0x8E);
|
SetGate(29, (addr_t) isr29, 0x08, 0x8E);
|
||||||
SetGate(30, (uint32_t) isr30, 0x08, 0x8E);
|
SetGate(30, (addr_t) isr30, 0x08, 0x8E);
|
||||||
SetGate(31, (uint32_t) isr31, 0x08, 0x8E);
|
SetGate(31, (addr_t) isr31, 0x08, 0x8E);
|
||||||
SetGate(32, (uint32_t) irq0, 0x08, 0x8E);
|
SetGate(32, (addr_t) irq0, 0x08, 0x8E);
|
||||||
SetGate(33, (uint32_t) irq1, 0x08, 0x8E);
|
SetGate(33, (addr_t) irq1, 0x08, 0x8E);
|
||||||
SetGate(34, (uint32_t) irq2, 0x08, 0x8E);
|
SetGate(34, (addr_t) irq2, 0x08, 0x8E);
|
||||||
SetGate(35, (uint32_t) irq3, 0x08, 0x8E);
|
SetGate(35, (addr_t) irq3, 0x08, 0x8E);
|
||||||
SetGate(36, (uint32_t) irq4, 0x08, 0x8E);
|
SetGate(36, (addr_t) irq4, 0x08, 0x8E);
|
||||||
SetGate(37, (uint32_t) irq5, 0x08, 0x8E);
|
SetGate(37, (addr_t) irq5, 0x08, 0x8E);
|
||||||
SetGate(38, (uint32_t) irq6, 0x08, 0x8E);
|
SetGate(38, (addr_t) irq6, 0x08, 0x8E);
|
||||||
SetGate(39, (uint32_t) irq7, 0x08, 0x8E);
|
SetGate(39, (addr_t) irq7, 0x08, 0x8E);
|
||||||
SetGate(40, (uint32_t) irq8, 0x08, 0x8E);
|
SetGate(40, (addr_t) irq8, 0x08, 0x8E);
|
||||||
SetGate(41, (uint32_t) irq9, 0x08, 0x8E);
|
SetGate(41, (addr_t) irq9, 0x08, 0x8E);
|
||||||
SetGate(42, (uint32_t) irq10, 0x08, 0x8E);
|
SetGate(42, (addr_t) irq10, 0x08, 0x8E);
|
||||||
SetGate(43, (uint32_t) irq11, 0x08, 0x8E);
|
SetGate(43, (addr_t) irq11, 0x08, 0x8E);
|
||||||
SetGate(44, (uint32_t) irq12, 0x08, 0x8E);
|
SetGate(44, (addr_t) irq12, 0x08, 0x8E);
|
||||||
SetGate(45, (uint32_t) irq13, 0x08, 0x8E);
|
SetGate(45, (addr_t) irq13, 0x08, 0x8E);
|
||||||
SetGate(46, (uint32_t) irq14, 0x08, 0x8E);
|
SetGate(46, (addr_t) irq14, 0x08, 0x8E);
|
||||||
SetGate(47, (uint32_t) irq15, 0x08, 0x8E);
|
SetGate(47, (addr_t) irq15, 0x08, 0x8E);
|
||||||
SetGate(128, (uint32_t) syscall_handler, 0x08, 0x8E | 0x60); // System Calls
|
SetGate(128, (addr_t) syscall_handler, 0x08, 0x8E | 0x60); // System Calls
|
||||||
|
|
||||||
idt_flush((uint32_t)&idt_ptr);
|
idt_flush((addr_t) &idt_ptr);
|
||||||
#else
|
|
||||||
#warning "IDT is not yet supported on this arch!"
|
|
||||||
while(true);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
|
void SetGate(uint8_t num, addr_t base, uint16_t sel, uint8_t flags)
|
||||||
{
|
{
|
||||||
idt_entries[num].base_lo = base & 0xFFFF;
|
idt_entries[num].base_low = base & 0xFFFF;
|
||||||
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
idt_entries[num].base_high = (base >> 16) & 0xFFFF;
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
idt_entries[num].base_highest = (base >> 32 ) & 0xFFFFFFFFU;
|
||||||
|
idt_entries[num].zero1 = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
idt_entries[num].sel = sel;
|
idt_entries[num].sel = sel;
|
||||||
idt_entries[num].always0 = 0;
|
idt_entries[num].always0 = 0;
|
||||||
|
|
|
@ -127,16 +127,34 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
|
|
||||||
// A struct describing an interrupt gate.
|
// A struct describing an interrupt gate.
|
||||||
struct idt_entry_struct
|
struct idt_entry32_struct
|
||||||
{
|
{
|
||||||
uint16_t base_lo; // The lower 16 bits of the address to jump to when this interrupt fires.
|
uint16_t base_low; // The lower 16 bits of the address to jump to when this interrupt fires.
|
||||||
uint16_t sel; // Kernel segment selector.
|
uint16_t sel; // Kernel segment selector.
|
||||||
uint8_t always0; // This must always be zero.
|
uint8_t always0; // This must always be zero.
|
||||||
uint8_t flags; // More flags. See documentation.
|
uint8_t flags; // More flags. See documentation.
|
||||||
uint16_t base_hi; // The upper 16 bits of the address to jump to.
|
uint16_t base_high; // The upper 16 bits of the address to jump to.
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef struct idt_entry_struct idt_entry_t;
|
struct idt_entry64_struct
|
||||||
|
{
|
||||||
|
uint16_t base_low; // The lower 16 bits of the address to jump to when this interrupt fires.
|
||||||
|
uint16_t sel; // Kernel segment selector.
|
||||||
|
uint8_t always0; // This must always be zero.
|
||||||
|
uint8_t flags; // More flags. See documentation.
|
||||||
|
uint16_t base_high; // The upper 16 bits of the address to jump to.
|
||||||
|
uint32_t base_highest;
|
||||||
|
uint32_t zero1; // Reserved
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct idt_entry32_struct idt_entry32_t;
|
||||||
|
typedef struct idt_entry64_struct idt_entry64_t;
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
typedef idt_entry64_t idt_entry_t;
|
||||||
|
#else
|
||||||
|
typedef idt_entry32_t idt_entry_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// A struct describing a pointer to an array of interrupt handlers.
|
// A struct describing a pointer to an array of interrupt handlers.
|
||||||
// This is in a format suitable for giving to 'lidt'.
|
// This is in a format suitable for giving to 'lidt'.
|
||||||
|
@ -149,7 +167,7 @@ namespace Sortix
|
||||||
typedef struct idt_ptr_struct idt_ptr_t;
|
typedef struct idt_ptr_struct idt_ptr_t;
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void SetGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
|
void SetGate(uint8_t num, addr_t base, uint16_t sel, uint8_t flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,14 @@ namespace Sortix
|
||||||
|
|
||||||
Handler interrupthandlers[256];
|
Handler interrupthandlers[256];
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < 256; i++ )
|
||||||
|
{
|
||||||
|
interrupthandlers[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterHandler(uint8_t n, Interrupt::Handler handler)
|
void RegisterHandler(uint8_t n, Interrupt::Handler handler)
|
||||||
{
|
{
|
||||||
interrupthandlers[n] = handler;
|
interrupthandlers[n] = handler;
|
||||||
|
@ -62,7 +70,6 @@ namespace Sortix
|
||||||
// This gets called from our ASM interrupt handler stub.
|
// This gets called from our ASM interrupt handler stub.
|
||||||
extern "C" void ISRHandler(Sortix::CPU::InterruptRegisters* regs)
|
extern "C" void ISRHandler(Sortix::CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_X86
|
|
||||||
if ( regs->int_no < 32 )
|
if ( regs->int_no < 32 )
|
||||||
{
|
{
|
||||||
const char* message = ( regs->int_no < numknownexceptions )
|
const char* message = ( regs->int_no < numknownexceptions )
|
||||||
|
@ -70,17 +77,23 @@ namespace Sortix
|
||||||
|
|
||||||
if ( DEBUG_EXCEPTION ) { regs->LogRegisters(); Log::Print("\n"); }
|
if ( DEBUG_EXCEPTION ) { regs->LogRegisters(); Log::Print("\n"); }
|
||||||
|
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
addr_t ip = regs->rip;
|
||||||
|
#else
|
||||||
|
addr_t ip = regs->eip;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Halt and catch fire if we are the kernel.
|
// Halt and catch fire if we are the kernel.
|
||||||
if ( (regs->cs & (0x4-1)) == 0 )
|
if ( (regs->cs & (0x4-1)) == 0 )
|
||||||
{
|
{
|
||||||
PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx "
|
PanicF("Unhandled CPU Exception id %zu '%s' at ip=0x%zx "
|
||||||
"(cr2=0x%p, err_code=0x%p)", regs->int_no, message,
|
"(cr2=0x%p, err_code=0x%p)", regs->int_no, message,
|
||||||
regs->eip, regs->cr2, regs->err_code);
|
ip, regs->cr2, regs->err_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Print("The current program has crashed and was terminated:\n");
|
Log::Print("The current program has crashed and was terminated:\n");
|
||||||
Log::PrintF("%s exception at eip=0x%zx (cr2=0x%p, err_code=0x%p)\n",
|
Log::PrintF("%s exception at ip=0x%zx (cr2=0x%p, err_code=0x%p)\n",
|
||||||
message, regs->eip, regs->cr2, regs->err_code);
|
message, ip, regs->cr2, regs->err_code);
|
||||||
|
|
||||||
Sound::Mute();
|
Sound::Mute();
|
||||||
|
|
||||||
|
@ -94,16 +107,11 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
interrupthandlers[regs->int_no](regs);
|
interrupthandlers[regs->int_no](regs);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#warning "ISR handlers are not supported on this arch"
|
|
||||||
while(true);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gets called from our ASM interrupt handler stub.
|
// This gets called from our ASM interrupt handler stub.
|
||||||
extern "C" void IRQHandler(Sortix::CPU::InterruptRegisters* regs)
|
extern "C" void IRQHandler(Sortix::CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_X86
|
|
||||||
// TODO! IRQ 7 and 15 might be spurious and might need to be ignored.
|
// 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).
|
// See http://wiki.osdev.org/PIC for details (section Spurious IRQs).
|
||||||
if ( regs->int_no == 32 + 7 || regs->int_no == 32 + 15 ) { return; }
|
if ( regs->int_no == 32 + 7 || regs->int_no == 32 + 15 ) { return; }
|
||||||
|
@ -115,28 +123,25 @@ namespace Sortix
|
||||||
Log::Print("\n");
|
Log::Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( regs->int_no < 32 || 48 < regs->int_no )
|
|
||||||
{
|
|
||||||
PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!",
|
|
||||||
regs->eax, regs->int_no, regs->err_code, regs->eip);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send an EOI (end of interrupt) signal to the PICs.
|
// Send an EOI (end of interrupt) signal to the PICs.
|
||||||
|
|
||||||
// Send reset signal to slave if this interrupt involved the slave.
|
// Send reset signal to slave if this interrupt involved the slave.
|
||||||
if (regs->int_no >= 40) { X86::OutPortB(0xA0, 0x20); }
|
if (regs->int_no >= 40) { CPU::OutPortB(0xA0, 0x20); }
|
||||||
|
|
||||||
// Send reset signal to master.
|
// Send reset signal to master.
|
||||||
X86::OutPortB(0x20, 0x20);
|
CPU::OutPortB(0x20, 0x20);
|
||||||
|
|
||||||
if ( interrupthandlers[regs->int_no] != NULL )
|
if ( interrupthandlers[regs->int_no] )
|
||||||
{
|
{
|
||||||
interrupthandlers[regs->int_no](regs);
|
interrupthandlers[regs->int_no](regs);
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
#warning "IRQ handlers are not supported on this arch"
|
|
||||||
while(true);
|
extern "C" void interrupt_handler(Sortix::CPU::InterruptRegisters* regs)
|
||||||
#endif
|
{
|
||||||
|
size_t int_no = regs->int_no;
|
||||||
|
if ( 32 <= int_no && int_no < 48 ) { IRQHandler(regs); }
|
||||||
|
else { ISRHandler(regs); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace Sortix
|
||||||
typedef void (*Handler)(CPU::InterruptRegisters* Registers);
|
typedef void (*Handler)(CPU::InterruptRegisters* Registers);
|
||||||
|
|
||||||
void RegisterHandler(uint8_t n, Handler handler);
|
void RegisterHandler(uint8_t n, Handler handler);
|
||||||
|
|
||||||
|
void Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
|
#include "interrupt.h"
|
||||||
|
|
||||||
using namespace Maxsi;
|
using namespace Maxsi;
|
||||||
|
|
||||||
|
@ -183,6 +184,28 @@ namespace Sortix
|
||||||
// Display the boot welcome screen.
|
// Display the boot welcome screen.
|
||||||
DoWelcome();
|
DoWelcome();
|
||||||
|
|
||||||
|
if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); }
|
||||||
|
|
||||||
|
uint8_t* initrd = NULL;
|
||||||
|
size_t initrdsize = 0;
|
||||||
|
|
||||||
|
#ifndef JSSORTIX
|
||||||
|
uint32_t* modules = (uint32_t*) BootInfo->mods_addr;
|
||||||
|
for ( uint32_t I = 0; I < BootInfo->mods_count; I++ )
|
||||||
|
{
|
||||||
|
initrdsize = modules[2*I+1] - modules[2*I+0];
|
||||||
|
initrd = (uint8_t*) modules[2*I+0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( initrd == NULL ) { PanicF("No init ramdisk provided"); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
// TODO: UGLY HACK because JSVM doesn't support multiboot yet!
|
||||||
|
initrd = (uint8_t*) 0x180000UL;
|
||||||
|
initrdsize = 0x80000; // 512 KiB
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef JSSORTIX
|
#ifndef JSSORTIX
|
||||||
// Search for PCI devices and load their drivers.
|
// Search for PCI devices and load their drivers.
|
||||||
PCI::Init();
|
PCI::Init();
|
||||||
|
@ -191,41 +214,15 @@ namespace Sortix
|
||||||
// Initialize the paging and virtual memory.
|
// Initialize the paging and virtual memory.
|
||||||
Memory::Init(BootInfo);
|
Memory::Init(BootInfo);
|
||||||
|
|
||||||
uint8_t* initrd = NULL;
|
|
||||||
size_t initrdsize = 0;
|
|
||||||
|
|
||||||
#ifndef JSSORTIX
|
|
||||||
uint8_t** modules = (uint8_t**) BootInfo->mods_addr;
|
|
||||||
for ( uint32_t I = 0; I < BootInfo->mods_count; I++ )
|
|
||||||
{
|
|
||||||
initrdsize = modules[2*I+1] - modules[2*I+0];
|
|
||||||
initrd = modules[2*I+0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// TODO: UGLY HACK because JSVM doesn't support multiboot yet!
|
|
||||||
initrd = (uint8_t*) 0x180000UL;
|
|
||||||
initrdsize = 0x80000; // 512 KiB
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( initrd == NULL ) { PanicF("No initrd provided"); }
|
|
||||||
|
|
||||||
// Initialize the GDT and TSS structures.
|
// Initialize the GDT and TSS structures.
|
||||||
GDT::Init();
|
GDT::Init();
|
||||||
|
|
||||||
#ifdef PLATFORM_X64
|
// Initialize the interrupt handler table to zeroes.
|
||||||
Log::Print("Halt: CPU x64 cannot boot because interrupts are not yet "
|
Interrupt::Init();
|
||||||
"supported under 64-bit Sortix.\n");
|
|
||||||
Log::Print("Sorry, it simply isn't possible to fully boot Sortix in x64 mode yet.\n");
|
|
||||||
Log::Print("x64 may be working when Sortix 0.6 comes out, or try the git master.\n");
|
|
||||||
while(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initialize the interrupt descriptor tables.
|
// Initialize the interrupt descriptor tables (enabling interrupts).
|
||||||
IDT::Init();
|
IDT::Init();
|
||||||
|
|
||||||
if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); }
|
|
||||||
|
|
||||||
// Initialize the kernel heap.
|
// Initialize the kernel heap.
|
||||||
Maxsi::Memory::Init();
|
Maxsi::Memory::Init();
|
||||||
|
|
||||||
|
@ -265,6 +262,13 @@ namespace Sortix
|
||||||
// Set up the initial ram disk.
|
// Set up the initial ram disk.
|
||||||
InitRD::Init(initrd, initrdsize);
|
InitRD::Init(initrd, initrdsize);
|
||||||
|
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
Log::Print("Halt: There is no program loader for 64-bit Sortix\n");
|
||||||
|
Log::Print("Sorry, it simply isn't possible to fully boot Sortix in x64 mode yet.\n");
|
||||||
|
Log::Print("x64 may be working when Sortix 0.5 comes out, or try the git master.\n");
|
||||||
|
while(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Alright, now the system's drivers are loaded and initialized. It is
|
// Alright, now the system's drivers are loaded and initialized. It is
|
||||||
// time to load the initial user-space programs and start execution of
|
// time to load the initial user-space programs and start execution of
|
||||||
// the actual operating system.
|
// the actual operating system.
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
.globl start, _start
|
.globl start, _start
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
.text 0x100000
|
.text 0x100000
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
.code32
|
.code32
|
||||||
|
|
|
@ -36,9 +36,11 @@ gdt_flush:
|
||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
|
mov %ax, %ss
|
||||||
|
|
||||||
# 0x08 is the offset to our code segment: Far jump!
|
# Far jump to our new code segment!
|
||||||
ljmp *GDT_FLUSH_POSTJMP
|
movq $GDT_FLUSH_POSTJMP, %rax
|
||||||
|
ljmp *(%rax)
|
||||||
gdt_flush_postjmp:
|
gdt_flush_postjmp:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -67,5 +69,5 @@ tss_flush:
|
||||||
.section .data
|
.section .data
|
||||||
GDT_FLUSH_POSTJMP:
|
GDT_FLUSH_POSTJMP:
|
||||||
.long gdt_flush_postjmp
|
.long gdt_flush_postjmp
|
||||||
.word 0x08
|
.word 0x08 # 0x08 is the offset to our code segment
|
||||||
|
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
;
|
|
||||||
; interrupt.s -- Contains interrupt service routine wrappers.
|
|
||||||
; Based on Bran's kernel development tutorials.
|
|
||||||
; Rewritten for JamesM's kernel development tutorials.
|
|
||||||
|
|
||||||
; This macro creates a stub for an ISR which does NOT pass it's own
|
|
||||||
; error code (adds a dummy errcode byte).
|
|
||||||
%macro ISR_NOERRCODE 1
|
|
||||||
global isr%1
|
|
||||||
isr%1:
|
|
||||||
cli ; Disable interrupts firstly.
|
|
||||||
push long 0 ; Push a dummy error code.
|
|
||||||
push long %1 ; Push the interrupt number.
|
|
||||||
jmp isr_common_stub ; Go to our common handler code.
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; This macro creates a stub for an ISR which passes it's own
|
|
||||||
; error code.
|
|
||||||
%macro ISR_ERRCODE 1
|
|
||||||
global isr%1
|
|
||||||
isr%1:
|
|
||||||
cli ; Disable interrupts.
|
|
||||||
push long %1 ; Push the interrupt number
|
|
||||||
jmp isr_common_stub
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
; This macro creates a stub for an IRQ - the first parameter is
|
|
||||||
; the IRQ number, the second is the ISR number it is remapped to.
|
|
||||||
%macro IRQ 2
|
|
||||||
global irq%1
|
|
||||||
irq%1:
|
|
||||||
cli
|
|
||||||
push long 0
|
|
||||||
push long %2
|
|
||||||
jmp irq_common_stub
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
ISR_NOERRCODE 0
|
|
||||||
ISR_NOERRCODE 1
|
|
||||||
ISR_NOERRCODE 2
|
|
||||||
ISR_NOERRCODE 3
|
|
||||||
ISR_NOERRCODE 4
|
|
||||||
ISR_NOERRCODE 5
|
|
||||||
ISR_NOERRCODE 6
|
|
||||||
ISR_NOERRCODE 7
|
|
||||||
ISR_ERRCODE 8
|
|
||||||
ISR_NOERRCODE 9
|
|
||||||
ISR_ERRCODE 10
|
|
||||||
ISR_ERRCODE 11
|
|
||||||
ISR_ERRCODE 12
|
|
||||||
ISR_ERRCODE 13
|
|
||||||
ISR_ERRCODE 14
|
|
||||||
ISR_NOERRCODE 15
|
|
||||||
ISR_NOERRCODE 16
|
|
||||||
ISR_NOERRCODE 17
|
|
||||||
ISR_NOERRCODE 18
|
|
||||||
ISR_NOERRCODE 19
|
|
||||||
ISR_NOERRCODE 20
|
|
||||||
ISR_NOERRCODE 21
|
|
||||||
ISR_NOERRCODE 22
|
|
||||||
ISR_NOERRCODE 23
|
|
||||||
ISR_NOERRCODE 24
|
|
||||||
ISR_NOERRCODE 25
|
|
||||||
ISR_NOERRCODE 26
|
|
||||||
ISR_NOERRCODE 27
|
|
||||||
ISR_NOERRCODE 28
|
|
||||||
ISR_NOERRCODE 29
|
|
||||||
ISR_NOERRCODE 30
|
|
||||||
ISR_NOERRCODE 31
|
|
||||||
ISR_NOERRCODE 128
|
|
||||||
ISR_NOERRCODE 177
|
|
||||||
IRQ 0, 32
|
|
||||||
IRQ 1, 33
|
|
||||||
IRQ 2, 34
|
|
||||||
IRQ 3, 35
|
|
||||||
IRQ 4, 36
|
|
||||||
IRQ 5, 37
|
|
||||||
IRQ 6, 38
|
|
||||||
IRQ 7, 39
|
|
||||||
IRQ 8, 40
|
|
||||||
IRQ 9, 41
|
|
||||||
IRQ 10, 42
|
|
||||||
IRQ 11, 43
|
|
||||||
IRQ 12, 44
|
|
||||||
IRQ 13, 45
|
|
||||||
IRQ 14, 46
|
|
||||||
IRQ 15, 47
|
|
||||||
|
|
||||||
; In isr.c
|
|
||||||
extern isr_handler
|
|
||||||
|
|
||||||
; This is our common ISR stub. It saves the processor state, sets
|
|
||||||
; up for kernel mode segments, calls the C-level fault handler,
|
|
||||||
; and finally restores the stack frame.
|
|
||||||
isr_common_stub:
|
|
||||||
|
|
||||||
; TODO
|
|
||||||
|
|
||||||
; In isr.c
|
|
||||||
extern irq_handler
|
|
||||||
|
|
||||||
; This is our common IRQ stub. It saves the processor state, sets
|
|
||||||
; up for kernel mode segments, calls the C-level fault handler,
|
|
||||||
; and finally restores the stack frame.
|
|
||||||
irq_common_stub:
|
|
||||||
|
|
||||||
; TODO
|
|
||||||
|
|
|
@ -0,0 +1,440 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix is free software: you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
x63/interrupt.s
|
||||||
|
Transfers control to interrupt handlers when interrupts happen.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.global isr0
|
||||||
|
.type isr0, @function
|
||||||
|
isr0:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $0 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr1
|
||||||
|
.type isr1, @function
|
||||||
|
isr1:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $1 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr2
|
||||||
|
.type isr2, @function
|
||||||
|
isr2:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $2 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr3
|
||||||
|
.type isr3, @function
|
||||||
|
isr3:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $3 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr4
|
||||||
|
.type isr4, @function
|
||||||
|
isr4:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $4 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr5
|
||||||
|
.type isr5, @function
|
||||||
|
isr5:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $5 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr6
|
||||||
|
.type isr6, @function
|
||||||
|
isr6:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $6 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr7
|
||||||
|
.type isr7, @function
|
||||||
|
isr7:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $7 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr8
|
||||||
|
.type isr8, @function
|
||||||
|
isr8:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $8 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr9
|
||||||
|
.type isr9, @function
|
||||||
|
isr9:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $9 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr10
|
||||||
|
.type isr10, @function
|
||||||
|
isr10:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $10 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr11
|
||||||
|
.type isr11, @function
|
||||||
|
isr11:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $11 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr12
|
||||||
|
.type isr12, @function
|
||||||
|
isr12:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $12 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr13
|
||||||
|
.type isr13, @function
|
||||||
|
isr13:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $13 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr14
|
||||||
|
.type isr14, @function
|
||||||
|
isr14:
|
||||||
|
cli
|
||||||
|
# pushq $0 # err_code pushed by CPU
|
||||||
|
pushq $14 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr15
|
||||||
|
.type isr15, @function
|
||||||
|
isr15:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $15 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr16
|
||||||
|
.type isr16, @function
|
||||||
|
isr16:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $16 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr17
|
||||||
|
.type isr17, @function
|
||||||
|
isr17:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $17 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr18
|
||||||
|
.type isr18, @function
|
||||||
|
isr18:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $18 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr19
|
||||||
|
.type isr19, @function
|
||||||
|
isr19:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $19 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr20
|
||||||
|
.type isr20, @function
|
||||||
|
isr20:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $20 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr21
|
||||||
|
.type isr21, @function
|
||||||
|
isr21:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $21 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr22
|
||||||
|
.type isr22, @function
|
||||||
|
isr22:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $22 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr23
|
||||||
|
.type isr23, @function
|
||||||
|
isr23:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $23 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr24
|
||||||
|
.type isr24, @function
|
||||||
|
isr24:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $24 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr25
|
||||||
|
.type isr25, @function
|
||||||
|
isr25:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $25 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr26
|
||||||
|
.type isr26, @function
|
||||||
|
isr26:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $26 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr27
|
||||||
|
.type isr27, @function
|
||||||
|
isr27:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $27 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr28
|
||||||
|
.type isr28, @function
|
||||||
|
isr28:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $28 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr29
|
||||||
|
.type isr29, @function
|
||||||
|
isr29:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $29 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr30
|
||||||
|
.type isr30, @function
|
||||||
|
isr30:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $30 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr31
|
||||||
|
.type isr31, @function
|
||||||
|
isr31:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $31 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global isr128
|
||||||
|
.type isr128, @function
|
||||||
|
isr128:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $128 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq0
|
||||||
|
.type irq0, @function
|
||||||
|
irq0:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $32 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq1
|
||||||
|
.type irq1, @function
|
||||||
|
irq1:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $33 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq2
|
||||||
|
.type irq2, @function
|
||||||
|
irq2:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $34 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq3
|
||||||
|
.type irq3, @function
|
||||||
|
irq3:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $35 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq4
|
||||||
|
.type irq4, @function
|
||||||
|
irq4:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $36 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq5
|
||||||
|
.type irq5, @function
|
||||||
|
irq5:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $37 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq6
|
||||||
|
.type irq6, @function
|
||||||
|
irq6:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $38 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq7
|
||||||
|
.type irq7, @function
|
||||||
|
irq7:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $39 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq8
|
||||||
|
.type irq8, @function
|
||||||
|
irq8:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $40 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq9
|
||||||
|
.type irq9, @function
|
||||||
|
irq9:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $41 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq10
|
||||||
|
.type irq10, @function
|
||||||
|
irq10:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $42 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq11
|
||||||
|
.type irq11, @function
|
||||||
|
irq11:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $43 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq12
|
||||||
|
.type irq12, @function
|
||||||
|
irq12:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $44 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq13
|
||||||
|
.type irq13, @function
|
||||||
|
irq13:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $45 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq14
|
||||||
|
.type irq14, @function
|
||||||
|
irq14:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $46 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
.global irq15
|
||||||
|
.type irq15, @function
|
||||||
|
irq15:
|
||||||
|
cli
|
||||||
|
pushq $0 # err_code
|
||||||
|
pushq $47 # int_no
|
||||||
|
jmp interrupt_handler_prepare
|
||||||
|
|
||||||
|
interrupt_handler_prepare:
|
||||||
|
pushq %r15
|
||||||
|
pushq %r14
|
||||||
|
pushq %r13
|
||||||
|
pushq %r12
|
||||||
|
pushq %r11
|
||||||
|
pushq %r10
|
||||||
|
pushq %r9
|
||||||
|
pushq %r8
|
||||||
|
pushq %rax
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rbx
|
||||||
|
pushq %rsp
|
||||||
|
pushq %rbp
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdi
|
||||||
|
|
||||||
|
# Push the user-space data segment.
|
||||||
|
movl %ds, %ebp
|
||||||
|
pushq %rbp
|
||||||
|
|
||||||
|
# Load the kernel data segment.
|
||||||
|
movw $0x10, %bp
|
||||||
|
movl %ebp, %ds
|
||||||
|
movl %ebp, %es
|
||||||
|
movl %ebp, %fs
|
||||||
|
movl %ebp, %gs
|
||||||
|
|
||||||
|
# Push CR2 in case of page faults
|
||||||
|
movq %cr2, %rbp
|
||||||
|
pushq %rbp
|
||||||
|
|
||||||
|
# Now call the interrupt handler.
|
||||||
|
movq %rsp, %rdi
|
||||||
|
call interrupt_handler
|
||||||
|
|
||||||
|
# Remove CR2 from the stack.
|
||||||
|
addq $8, %rsp
|
||||||
|
|
||||||
|
# Restore the user-space data segment.
|
||||||
|
popq %rbp
|
||||||
|
movl %ebp, %ds
|
||||||
|
movl %ebp, %es
|
||||||
|
movl %ebp, %fs
|
||||||
|
movl %ebp, %gs
|
||||||
|
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
popq %rbp
|
||||||
|
popq %rsp
|
||||||
|
popq %rbx
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %rax
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
popq %r10
|
||||||
|
popq %r11
|
||||||
|
popq %r12
|
||||||
|
popq %r13
|
||||||
|
popq %r14
|
||||||
|
popq %r15
|
||||||
|
|
||||||
|
# Remove int_no and err_code
|
||||||
|
addq $16, %rsp
|
||||||
|
|
||||||
|
# Return to where we came from.
|
||||||
|
iretq
|
||||||
|
|
Loading…
Reference in New Issue