Compare commits
No commits in common. "db2814596b85435ca996a8d36fffedcc0344d1c3" and "d100ab53a8187901bff3d33bb0855a250c048dfd" have entirely different histories.
db2814596b
...
d100ab53a8
@ -26,7 +26,6 @@ import hulk.usb;
|
|||||||
import hulk.pit;
|
import hulk.pit;
|
||||||
import hulk.time;
|
import hulk.time;
|
||||||
import hulk.test;
|
import hulk.test;
|
||||||
import hulk.thread;
|
|
||||||
|
|
||||||
extern extern(C) __gshared ubyte _hulk_bss_size;
|
extern extern(C) __gshared ubyte _hulk_bss_size;
|
||||||
|
|
||||||
@ -34,7 +33,7 @@ extern extern(C) __gshared ubyte _hulk_bss_size;
|
|||||||
private __gshared HulkHeader hulk_header = {
|
private __gshared HulkHeader hulk_header = {
|
||||||
&_hulk_bss_size, /* hulk_bss_size */
|
&_hulk_bss_size, /* hulk_bss_size */
|
||||||
&hulk_start, /* entry */
|
&hulk_start, /* entry */
|
||||||
Thread.STACK_SIZE, /* stack_size */
|
16u * 1024u, /* stack_size */
|
||||||
Hurl.HULK_BASE, /* virt_base */
|
Hurl.HULK_BASE, /* virt_base */
|
||||||
Hurl.HULK_STACK_TOP, /* virt_stack_top */
|
Hurl.HULK_STACK_TOP, /* virt_stack_top */
|
||||||
Hurl.HULK_FRAMEBUFFER, /* virt_fb_buffer */
|
Hurl.HULK_FRAMEBUFFER, /* virt_fb_buffer */
|
||||||
@ -89,14 +88,18 @@ void hulk_start()
|
|||||||
Pit.initialize();
|
Pit.initialize();
|
||||||
Pci.initialize();
|
Pci.initialize();
|
||||||
Usb.initialize();
|
Usb.initialize();
|
||||||
Thread.initialize();
|
|
||||||
|
|
||||||
resume_interrupts();
|
resume_interrupts();
|
||||||
|
|
||||||
Test.run();
|
/* Check that PIT millisecond interrupt is firing. */
|
||||||
|
size_t uptime = Time.uptime();
|
||||||
|
while (Time.uptime() <= uptime)
|
||||||
|
{
|
||||||
|
}
|
||||||
Klog.writefln("\a5HULK Initialization Complete!");
|
Klog.writefln("\a5HULK Initialization Complete!");
|
||||||
|
|
||||||
/* Run kernel tests. */
|
/* Run kernel tests. */
|
||||||
|
Test.run();
|
||||||
|
|
||||||
/* Idle loop. */
|
/* Idle loop. */
|
||||||
Time.msleep(1);
|
Time.msleep(1);
|
||||||
|
@ -11,12 +11,11 @@ import hulk.klog;
|
|||||||
import hulk.apic;
|
import hulk.apic;
|
||||||
import hulk.cpu;
|
import hulk.cpu;
|
||||||
import hulk.kfont;
|
import hulk.kfont;
|
||||||
import hulk.thread;
|
|
||||||
|
|
||||||
struct Idt
|
struct Idt
|
||||||
{
|
{
|
||||||
/** Interrupt stack frame indices. */
|
/** Interrupt stack frame indices. */
|
||||||
public static enum
|
private static enum
|
||||||
{
|
{
|
||||||
ISF_RBP,
|
ISF_RBP,
|
||||||
ISF_R15,
|
ISF_R15,
|
||||||
@ -148,7 +147,7 @@ struct Idt
|
|||||||
mov $$", isr, ", %rdi
|
mov $$", isr, ", %rdi
|
||||||
movabs $$isr, %rax
|
movabs $$isr, %rax
|
||||||
callq *%rax
|
callq *%rax
|
||||||
mov %rax, %rsp
|
mov %rbp, %rsp
|
||||||
popq %rbp
|
popq %rbp
|
||||||
popq %r15
|
popq %r15
|
||||||
popq %r14
|
popq %r14
|
||||||
@ -185,15 +184,8 @@ struct Idt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public extern(C) void isr(ulong vector, ulong * stack_frame)
|
||||||
* Interrupt service routine.
|
|
||||||
*
|
|
||||||
* This function returns the stack pointer of the thread to execute when
|
|
||||||
* returning from this function.
|
|
||||||
*/
|
|
||||||
public extern(C) ulong * isr(ulong vector, ulong * 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 >= Idt.INT_APIC_BASE) && (vector < (Idt.INT_APIC_BASE + Idt.INT_APIC_COUNT)))
|
||||||
{
|
{
|
||||||
Apic.isr(vector);
|
Apic.isr(vector);
|
||||||
@ -225,5 +217,4 @@ public extern(C) ulong * isr(ulong vector, ulong * stack_frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Thread.current_thread.stack_pointer;
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ module hulk.test;
|
|||||||
|
|
||||||
import hulk.klog;
|
import hulk.klog;
|
||||||
import hulk.list;
|
import hulk.list;
|
||||||
import hulk.time;
|
|
||||||
|
|
||||||
struct Test
|
struct Test
|
||||||
{
|
{
|
||||||
@ -15,21 +14,10 @@ struct Test
|
|||||||
public static void run()
|
public static void run()
|
||||||
{
|
{
|
||||||
Klog.writefln("\a3Running kernel tests");
|
Klog.writefln("\a3Running kernel tests");
|
||||||
test_pit();
|
|
||||||
test_list();
|
test_list();
|
||||||
Klog.writefln("\a3Kernel tests complete");
|
Klog.writefln("\a3Kernel tests complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void test_pit()
|
|
||||||
{
|
|
||||||
Klog.writefln("Testing PIT...");
|
|
||||||
/* Check that PIT millisecond interrupt is firing. */
|
|
||||||
size_t uptime = Time.uptime();
|
|
||||||
while (Time.uptime() <= uptime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void test_list()
|
private static void test_list()
|
||||||
{
|
{
|
||||||
Klog.writefln("Testing list...");
|
Klog.writefln("Testing list...");
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
/**
|
|
||||||
* Kernel thread functionality.
|
|
||||||
*/
|
|
||||||
module hulk.thread;
|
|
||||||
|
|
||||||
import hulk.hurl.a1;
|
|
||||||
import hulk.idt;
|
|
||||||
import hulk.gdt;
|
|
||||||
import hulk.memory;
|
|
||||||
import hulk.list;
|
|
||||||
import hulk.cpu;
|
|
||||||
import hulk.hurl;
|
|
||||||
|
|
||||||
struct Thread
|
|
||||||
{
|
|
||||||
/* TODO: currently kernel thread stack size is fixed. */
|
|
||||||
enum STACK_SIZE = 16 * 1024;
|
|
||||||
|
|
||||||
/** List of all kernel threads. */
|
|
||||||
private static __gshared List!Thread threads;
|
|
||||||
|
|
||||||
/** Currently executing kernel thread. */
|
|
||||||
static __gshared Thread * current_thread;
|
|
||||||
|
|
||||||
/** Current kernel thread stack pointer. */
|
|
||||||
ulong * stack_pointer;
|
|
||||||
static assert(stack_pointer.offsetof == 0);
|
|
||||||
|
|
||||||
/** Base address of kernel thread stack. */
|
|
||||||
void * stack_addr;
|
|
||||||
|
|
||||||
/** Interrupt stack template. */
|
|
||||||
static immutable __gshared ulong[Idt.ISF_COUNT] interrupt_stack_template = [
|
|
||||||
0x16161616_16161616u, /* RBP */
|
|
||||||
0x15151515_15151515u, /* R15 */
|
|
||||||
0x14141414_14141414u, /* R14 */
|
|
||||||
0x13131313_13131313u, /* R13 */
|
|
||||||
0x12121212_12121212u, /* R12 */
|
|
||||||
0x11111111_11111111u, /* R11 */
|
|
||||||
0x10101010_10101010u, /* R10 */
|
|
||||||
0x09090909_09090909u, /* R9 */
|
|
||||||
0x08080808_08080808u, /* R8 */
|
|
||||||
0x06060606_06060606u, /* RDI */
|
|
||||||
0x05050505_05050505u, /* RSI */
|
|
||||||
0x04040404_04040404u, /* RDX */
|
|
||||||
0x03030303_03030303u, /* RCX */
|
|
||||||
0x02020202_02020202u, /* RBX */
|
|
||||||
0x01010101_01010101u, /* RAX */
|
|
||||||
0u, /* Error Code */
|
|
||||||
0u, /* RIP */
|
|
||||||
Gdt.SELECTOR_KERNEL_CODE, /* CS */
|
|
||||||
0u, /* RFLAGS */
|
|
||||||
0u, /* RSP */
|
|
||||||
Gdt.SELECTOR_KERNEL_DATA, /* SS */
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a kernel thread.
|
|
||||||
*/
|
|
||||||
public void initialize(void function() fn)
|
|
||||||
{
|
|
||||||
stack_addr = A1.allocate(STACK_SIZE);
|
|
||||||
ulong * stack_top = cast(ulong *)(stack_addr + STACK_SIZE);
|
|
||||||
stack_pointer = stack_top - Idt.ISF_COUNT;
|
|
||||||
memcpy64(stack_pointer, &interrupt_stack_template[0], Idt.ISF_COUNT);
|
|
||||||
stack_pointer[Idt.ISF_RIP] = cast(ulong)fn;
|
|
||||||
stack_pointer[Idt.ISF_RFLAGS] = read_rflags();
|
|
||||||
stack_pointer[Idt.ISF_RSP] = cast(ulong)stack_top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize main kernel thread.
|
|
||||||
*/
|
|
||||||
public void initialize_main_thread()
|
|
||||||
{
|
|
||||||
stack_addr = cast(void *)(Hurl.HULK_STACK_TOP - STACK_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize kernel threading.
|
|
||||||
*/
|
|
||||||
public static void initialize()
|
|
||||||
{
|
|
||||||
Thread * thread = A1.allocate!Thread();
|
|
||||||
thread.initialize_main_thread();
|
|
||||||
current_thread = thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and start a kernel thread.
|
|
||||||
*
|
|
||||||
* TODO: fn must not return.
|
|
||||||
* TODO: threads are always runnable.
|
|
||||||
* TODO: threads cannot be destroyed.
|
|
||||||
*/
|
|
||||||
public static Thread * start(void function() fn)
|
|
||||||
{
|
|
||||||
Thread * thread = A1.allocate!Thread();
|
|
||||||
thread.initialize(fn);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user