Rename hulk.idt to hulk.him
This commit is contained in:
parent
0efe8af5aa
commit
73f4d6b728
@ -5,7 +5,7 @@ module hulk.apic;
|
|||||||
|
|
||||||
import hulk.hurl;
|
import hulk.hurl;
|
||||||
import hulk.acpi;
|
import hulk.acpi;
|
||||||
import hulk.idt;
|
import hulk.him;
|
||||||
import hulk.rtc;
|
import hulk.rtc;
|
||||||
import hulk.pit;
|
import hulk.pit;
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
@ -180,7 +180,7 @@ struct Apic
|
|||||||
|
|
||||||
case Entry.IO_APIC_INTERRUPT_SOURCE_OVERRIDE:
|
case Entry.IO_APIC_INTERRUPT_SOURCE_OVERRIDE:
|
||||||
Entry2 * e = cast(Entry2 *)entry;
|
Entry2 * e = cast(Entry2 *)entry;
|
||||||
if (e.global_system_interrupt < Idt.INT_APIC_COUNT)
|
if (e.global_system_interrupt < INT_APIC_COUNT)
|
||||||
{
|
{
|
||||||
irq_redirects[e.irq_source] = cast(ubyte)e.global_system_interrupt;
|
irq_redirects[e.irq_source] = cast(ubyte)e.global_system_interrupt;
|
||||||
}
|
}
|
||||||
@ -307,8 +307,8 @@ struct Apic
|
|||||||
alias ISRHandler = void function();
|
alias ISRHandler = void function();
|
||||||
private static __gshared ApicRegisters * apic_registers;
|
private static __gshared ApicRegisters * apic_registers;
|
||||||
private static __gshared IoApicRegisters * io_apic_registers;
|
private static __gshared IoApicRegisters * io_apic_registers;
|
||||||
private static __gshared ISRHandler[Idt.INT_APIC_COUNT] irq_handlers;
|
private static __gshared ISRHandler[INT_APIC_COUNT] irq_handlers;
|
||||||
private static __gshared ubyte[Idt.INT_APIC_COUNT] irq_redirects;
|
private static __gshared ubyte[INT_APIC_COUNT] irq_redirects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize APIC.
|
* Initialize APIC.
|
||||||
@ -317,7 +317,7 @@ struct Apic
|
|||||||
{
|
{
|
||||||
Klog.writefln("\a3Initializing APIC");
|
Klog.writefln("\a3Initializing APIC");
|
||||||
io_apic_registers = cast(IoApicRegisters *)DEFAULT_IO_APIC_ADDRESS;
|
io_apic_registers = cast(IoApicRegisters *)DEFAULT_IO_APIC_ADDRESS;
|
||||||
for (ubyte i = 0u; i < Idt.INT_APIC_COUNT; i++)
|
for (ubyte i = 0u; i < INT_APIC_COUNT; i++)
|
||||||
{
|
{
|
||||||
irq_redirects[i] = i;
|
irq_redirects[i] = i;
|
||||||
}
|
}
|
||||||
@ -331,10 +331,10 @@ struct Apic
|
|||||||
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
PT_WRITABLE | PT_WRITE_THROUGH | PT_DISABLE_CACHE | PT_NO_EXECUTE);
|
||||||
/* Enable local APIC to receive interrupts and set spurious interrupt
|
/* Enable local APIC to receive interrupts and set spurious interrupt
|
||||||
* vector to 0xFF. */
|
* vector to 0xFF. */
|
||||||
apic_registers.spurious_interrupt_vector.value = 0x100u | Idt.INT_APIC_SPURIOUS;
|
apic_registers.spurious_interrupt_vector.value = 0x100u | INT_APIC_SPURIOUS;
|
||||||
apic_registers.lvt_timer.value = Idt.INT_APIC_TIMER;
|
apic_registers.lvt_timer.value = INT_APIC_TIMER;
|
||||||
apic_registers.lvt_lint[0].value = Idt.INT_APIC_LINT0;
|
apic_registers.lvt_lint[0].value = INT_APIC_LINT0;
|
||||||
apic_registers.lvt_lint[1].value = Idt.INT_APIC_LINT1;
|
apic_registers.lvt_lint[1].value = INT_APIC_LINT1;
|
||||||
/* Enable PIT interrupt. */
|
/* Enable PIT interrupt. */
|
||||||
configure_io_apic_irq(IRQ_PIT, &Pit.isr);
|
configure_io_apic_irq(IRQ_PIT, &Pit.isr);
|
||||||
/* Enable RTC interrupt. */
|
/* Enable RTC interrupt. */
|
||||||
@ -347,7 +347,7 @@ struct Apic
|
|||||||
private static void configure_io_apic_irq(size_t orig_irq, ISRHandler isr_handler)
|
private static void configure_io_apic_irq(size_t orig_irq, ISRHandler isr_handler)
|
||||||
{
|
{
|
||||||
size_t io_apic_irq = irq_redirects[orig_irq];
|
size_t io_apic_irq = irq_redirects[orig_irq];
|
||||||
ulong entry = Idt.INT_APIC_BASE + io_apic_irq;
|
ulong entry = INT_APIC_BASE + io_apic_irq;
|
||||||
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u);
|
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u);
|
||||||
io_apic_registers.data.value = entry & 0xFFFF_FFFFu;
|
io_apic_registers.data.value = entry & 0xFFFF_FFFFu;
|
||||||
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u + 1u);
|
io_apic_registers.address.value = cast(uint)(0x10u + io_apic_irq * 2u + 1u);
|
||||||
@ -368,8 +368,8 @@ struct Apic
|
|||||||
*/
|
*/
|
||||||
public static void isr(ulong vector)
|
public static void isr(ulong vector)
|
||||||
{
|
{
|
||||||
ulong io_apic_irq = vector - Idt.INT_APIC_BASE;
|
ulong io_apic_irq = vector - INT_APIC_BASE;
|
||||||
if ((io_apic_irq < Idt.INT_APIC_COUNT) && (irq_handlers[io_apic_irq] != null))
|
if ((io_apic_irq < INT_APIC_COUNT) && (irq_handlers[io_apic_irq] != null))
|
||||||
{
|
{
|
||||||
irq_handlers[io_apic_irq]();
|
irq_handlers[io_apic_irq]();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* IDT (Interrupt Descriptor Table) functionality.
|
* HULK Interrupt Manager.
|
||||||
*/
|
*/
|
||||||
module hulk.idt;
|
module hulk.him;
|
||||||
|
|
||||||
import hulk.gdt;
|
import hulk.gdt;
|
||||||
import ldc.llvmasm;
|
import ldc.llvmasm;
|
||||||
@ -13,7 +13,75 @@ import hulk.cpu;
|
|||||||
import hulk.kfont;
|
import hulk.kfont;
|
||||||
import hulk.thread;
|
import hulk.thread;
|
||||||
|
|
||||||
static foreach(isr; 0 .. Idt.N_ISRS)
|
/** Number if Interrupt Service Routines. */
|
||||||
|
private enum N_ISRS = 256;
|
||||||
|
|
||||||
|
/** Interrupt stack frame indices. */
|
||||||
|
public static enum
|
||||||
|
{
|
||||||
|
ISF_RBP,
|
||||||
|
ISF_R15,
|
||||||
|
ISF_R14,
|
||||||
|
ISF_R13,
|
||||||
|
ISF_R12,
|
||||||
|
ISF_R11,
|
||||||
|
ISF_R10,
|
||||||
|
ISF_R9,
|
||||||
|
ISF_R8,
|
||||||
|
ISF_RDI,
|
||||||
|
ISF_RSI,
|
||||||
|
ISF_RDX,
|
||||||
|
ISF_RCX,
|
||||||
|
ISF_RBX,
|
||||||
|
ISF_RAX,
|
||||||
|
ISF_ERROR_CODE,
|
||||||
|
ISF_RIP,
|
||||||
|
ISF_CS,
|
||||||
|
ISF_RFLAGS,
|
||||||
|
ISF_RSP,
|
||||||
|
ISF_SS,
|
||||||
|
ISF_COUNT,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static __gshared string[ISF_COUNT] ISF_NAMES = [
|
||||||
|
"RBP",
|
||||||
|
"R15",
|
||||||
|
"R14",
|
||||||
|
"R13",
|
||||||
|
"R12",
|
||||||
|
"R11",
|
||||||
|
"R10",
|
||||||
|
"R9",
|
||||||
|
"R8",
|
||||||
|
"RDI",
|
||||||
|
"RSI",
|
||||||
|
"RDX",
|
||||||
|
"RCX",
|
||||||
|
"RBX",
|
||||||
|
"RAX",
|
||||||
|
"Error Code",
|
||||||
|
"RIP",
|
||||||
|
"CS",
|
||||||
|
"RFLAGS",
|
||||||
|
"RSP",
|
||||||
|
"SS",
|
||||||
|
];
|
||||||
|
|
||||||
|
/** Interrupt IDs. @{ */
|
||||||
|
public enum ulong INT_PAGE_FAULT = 0x0Eu;
|
||||||
|
|
||||||
|
/* The I/O APIC is configured to map IRQ 0 to interrupt 64 (0x40). */
|
||||||
|
public enum ulong INT_APIC_BASE = 0x40u; /* IRQ 0 */
|
||||||
|
public enum ulong INT_APIC_COUNT = 24u;
|
||||||
|
|
||||||
|
public enum ulong INT_APIC_TIMER = 0x70u;
|
||||||
|
public enum ulong INT_APIC_LINT0 = 0x71u;
|
||||||
|
public enum ulong INT_APIC_LINT1 = 0x72u;
|
||||||
|
public enum ulong INT_KERNEL_SWINT = 0x80u;
|
||||||
|
public enum ulong INT_APIC_SPURIOUS = 0xFFu;
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
static foreach(isr; 0 .. N_ISRS)
|
||||||
{
|
{
|
||||||
mixin(`private extern(C) void isr_`, isr, `();`);
|
mixin(`private extern(C) void isr_`, isr, `();`);
|
||||||
}
|
}
|
||||||
@ -30,76 +98,12 @@ private string isrs_list(int index = 0)()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin(`private static __gshared extern(C) void function()[Idt.N_ISRS] isrs = [`,
|
mixin(`private static __gshared extern(C) void function()[N_ISRS] isrs = [`,
|
||||||
isrs_list(),
|
isrs_list(),
|
||||||
`];`);
|
`];`);
|
||||||
|
|
||||||
struct Idt
|
struct Him
|
||||||
{
|
{
|
||||||
/** Interrupt stack frame indices. */
|
|
||||||
public static enum
|
|
||||||
{
|
|
||||||
ISF_RBP,
|
|
||||||
ISF_R15,
|
|
||||||
ISF_R14,
|
|
||||||
ISF_R13,
|
|
||||||
ISF_R12,
|
|
||||||
ISF_R11,
|
|
||||||
ISF_R10,
|
|
||||||
ISF_R9,
|
|
||||||
ISF_R8,
|
|
||||||
ISF_RDI,
|
|
||||||
ISF_RSI,
|
|
||||||
ISF_RDX,
|
|
||||||
ISF_RCX,
|
|
||||||
ISF_RBX,
|
|
||||||
ISF_RAX,
|
|
||||||
ISF_ERROR_CODE,
|
|
||||||
ISF_RIP,
|
|
||||||
ISF_CS,
|
|
||||||
ISF_RFLAGS,
|
|
||||||
ISF_RSP,
|
|
||||||
ISF_SS,
|
|
||||||
ISF_COUNT,
|
|
||||||
}
|
|
||||||
private static __gshared string[ISF_COUNT] ISF_NAMES = [
|
|
||||||
"RBP",
|
|
||||||
"R15",
|
|
||||||
"R14",
|
|
||||||
"R13",
|
|
||||||
"R12",
|
|
||||||
"R11",
|
|
||||||
"R10",
|
|
||||||
"R9",
|
|
||||||
"R8",
|
|
||||||
"RDI",
|
|
||||||
"RSI",
|
|
||||||
"RDX",
|
|
||||||
"RCX",
|
|
||||||
"RBX",
|
|
||||||
"RAX",
|
|
||||||
"Error Code",
|
|
||||||
"RIP",
|
|
||||||
"CS",
|
|
||||||
"RFLAGS",
|
|
||||||
"RSP",
|
|
||||||
"SS",
|
|
||||||
];
|
|
||||||
|
|
||||||
public enum ulong EXC_PAGE_FAULT = 14;
|
|
||||||
|
|
||||||
/* The I/O APIC is configured to map IRQ 0 to interrupt 64 (0x40). */
|
|
||||||
public enum ulong INT_APIC_BASE = 0x40u; /* IRQ 0 */
|
|
||||||
public enum ulong INT_APIC_COUNT = 24u;
|
|
||||||
|
|
||||||
public enum ulong INT_APIC_TIMER = 0x70u;
|
|
||||||
public enum ulong INT_APIC_LINT0 = 0x71u;
|
|
||||||
public enum ulong INT_APIC_LINT1 = 0x72u;
|
|
||||||
public enum ulong INT_KERNEL_SWINT = 0x80u;
|
|
||||||
public enum ulong INT_APIC_SPURIOUS = 0xFFu;
|
|
||||||
|
|
||||||
private enum N_ISRS = 256;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IDT descriptor entry type.
|
* IDT descriptor entry type.
|
||||||
*/
|
*/
|
||||||
@ -232,7 +236,7 @@ struct Idt
|
|||||||
public extern(C) ulong * isr(ulong vector, ulong * stack_frame)
|
public extern(C) ulong * isr(ulong vector, ulong * stack_frame)
|
||||||
{
|
{
|
||||||
Thread.current_thread.stack_pointer = stack_frame;
|
Thread.current_thread.stack_pointer = stack_frame;
|
||||||
if ((vector >= Idt.INT_APIC_BASE) && (vector < (Idt.INT_APIC_BASE + Idt.INT_APIC_COUNT)))
|
if ((vector >= INT_APIC_BASE) && (vector < (INT_APIC_BASE + INT_APIC_COUNT)))
|
||||||
{
|
{
|
||||||
Apic.isr(vector);
|
Apic.isr(vector);
|
||||||
}
|
}
|
||||||
@ -240,19 +244,19 @@ public extern(C) ulong * isr(ulong vector, ulong * stack_frame)
|
|||||||
{
|
{
|
||||||
switch (vector)
|
switch (vector)
|
||||||
{
|
{
|
||||||
case Idt.INT_APIC_TIMER:
|
case INT_APIC_TIMER:
|
||||||
case Idt.INT_APIC_LINT0:
|
case INT_APIC_LINT0:
|
||||||
case Idt.INT_APIC_LINT1:
|
case INT_APIC_LINT1:
|
||||||
case Idt.INT_APIC_SPURIOUS:
|
case INT_APIC_SPURIOUS:
|
||||||
Apic.isr(vector);
|
Apic.isr(vector);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Fb.rect(0, 0, Fb.width, Kfont.line_height, 0xCC0000u);
|
Fb.rect(0, 0, Fb.width, Kfont.line_height, 0xCC0000u);
|
||||||
Klog.writefln("\n **** Unhandled ISR %u ****", vector);
|
Klog.writefln("\n **** Unhandled ISR %u ****", vector);
|
||||||
for (size_t i = 0u; i < Idt.ISF_COUNT; i++)
|
for (size_t i = 0u; i < ISF_COUNT; i++)
|
||||||
{
|
{
|
||||||
Klog.writef(Idt.ISF_NAMES[i]);
|
Klog.writef(ISF_NAMES[i]);
|
||||||
Klog.writefln(" = 0x%x", stack_frame[i]);
|
Klog.writefln(" = 0x%x", stack_frame[i]);
|
||||||
}
|
}
|
||||||
Klog.writefln("CR2 = 0x%p", read_cr2());
|
Klog.writefln("CR2 = 0x%p", read_cr2());
|
@ -14,7 +14,7 @@ import hulk.hurl;
|
|||||||
import hulk.hippo;
|
import hulk.hippo;
|
||||||
import hulk.pci;
|
import hulk.pci;
|
||||||
import hulk.gdt;
|
import hulk.gdt;
|
||||||
import hulk.idt;
|
import hulk.him;
|
||||||
import hulk.cpu;
|
import hulk.cpu;
|
||||||
import ldc.llvmasm;
|
import ldc.llvmasm;
|
||||||
import hulk.pic;
|
import hulk.pic;
|
||||||
@ -65,7 +65,7 @@ void hulk_start()
|
|||||||
initialize_cpu();
|
initialize_cpu();
|
||||||
Serial.initialize();
|
Serial.initialize();
|
||||||
Gdt.initialize();
|
Gdt.initialize();
|
||||||
Idt.initialize();
|
Him.initialize();
|
||||||
Fb.initialize(cast(uint *)Hurl.HULK_FRAMEBUFFER,
|
Fb.initialize(cast(uint *)Hurl.HULK_FRAMEBUFFER,
|
||||||
cast(uint *)hulk_header.bootinfo.fb_buffer1_phys,
|
cast(uint *)hulk_header.bootinfo.fb_buffer1_phys,
|
||||||
hulk_header.bootinfo.fb.width,
|
hulk_header.bootinfo.fb.width,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
module hulk.thread;
|
module hulk.thread;
|
||||||
|
|
||||||
import hulk.hurl.a1;
|
import hulk.hurl.a1;
|
||||||
import hulk.idt;
|
import hulk.him;
|
||||||
import hulk.gdt;
|
import hulk.gdt;
|
||||||
import hulk.memory;
|
import hulk.memory;
|
||||||
import hulk.list;
|
import hulk.list;
|
||||||
@ -17,7 +17,7 @@ struct Thread
|
|||||||
enum STACK_SIZE = 16 * 1024;
|
enum STACK_SIZE = 16 * 1024;
|
||||||
|
|
||||||
/** Interrupt stack template. */
|
/** Interrupt stack template. */
|
||||||
static immutable __gshared ulong[Idt.ISF_COUNT] interrupt_stack_template = [
|
static immutable __gshared ulong[ISF_COUNT] interrupt_stack_template = [
|
||||||
0x16161616_16161616u, /* RBP */
|
0x16161616_16161616u, /* RBP */
|
||||||
0x15151515_15151515u, /* R15 */
|
0x15151515_15151515u, /* R15 */
|
||||||
0x14141414_14141414u, /* R14 */
|
0x14141414_14141414u, /* R14 */
|
||||||
@ -69,11 +69,11 @@ struct Thread
|
|||||||
list_insert_after(current_thread);
|
list_insert_after(current_thread);
|
||||||
stack_addr = A1.allocate(STACK_SIZE);
|
stack_addr = A1.allocate(STACK_SIZE);
|
||||||
ulong * stack_top = cast(ulong *)(stack_addr + STACK_SIZE);
|
ulong * stack_top = cast(ulong *)(stack_addr + STACK_SIZE);
|
||||||
stack_pointer = stack_top - Idt.ISF_COUNT;
|
stack_pointer = stack_top - ISF_COUNT;
|
||||||
memcpy64(stack_pointer, &interrupt_stack_template[0], Idt.ISF_COUNT);
|
memcpy64(stack_pointer, &interrupt_stack_template[0], ISF_COUNT);
|
||||||
stack_pointer[Idt.ISF_RIP] = cast(ulong)fn;
|
stack_pointer[ISF_RIP] = cast(ulong)fn;
|
||||||
stack_pointer[Idt.ISF_RFLAGS] = read_rflags();
|
stack_pointer[ISF_RFLAGS] = read_rflags();
|
||||||
stack_pointer[Idt.ISF_RSP] = cast(ulong)stack_top;
|
stack_pointer[ISF_RSP] = cast(ulong)stack_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user