diff --git a/src/kernel/gdt.s b/src/kernel/gdt.s new file mode 100644 index 0000000..ea549e6 --- /dev/null +++ b/src/kernel/gdt.s @@ -0,0 +1,35 @@ +extern g_idtr +extern g_gdtr + +global idt_write +idt_write: + lidt [rel g_idtr] + ret + +global idt_load +idt_load: + sidt [rel g_idtr] + ret + +global gdt_write +gdt_write: + lgdt [rel g_gdtr] + mov ax, si ; second arg is data segment + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + push qword rdi ; first arg is code segment + lea rax, [rel .next] + push rax + o64 retf +.next: + ltr dx + ret + +global gdt_load +gdt_load: + sgdt [rel g_gdtr] + ret + diff --git a/src/kernel/interrupt_isrs.inc b/src/kernel/interrupt_isrs.inc index 0cdefe2..de04469 100644 --- a/src/kernel/interrupt_isrs.inc +++ b/src/kernel/interrupt_isrs.inc @@ -134,6 +134,109 @@ IRQ (0x7d, 0x5d, irq5D) IRQ (0x7e, 0x5e, irq5E) IRQ (0x7f, 0x5f, irq5F) +IRQ (0x80, 0x60, irq60) +IRQ (0x81, 0x61, irq61) +IRQ (0x82, 0x62, irq62) +IRQ (0x83, 0x63, irq63) +IRQ (0x84, 0x64, irq64) +IRQ (0x85, 0x65, irq65) +IRQ (0x86, 0x66, irq66) +IRQ (0x87, 0x67, irq67) +IRQ (0x88, 0x68, irq68) +IRQ (0x89, 0x69, irq69) +IRQ (0x8a, 0x6a, irq6A) +IRQ (0x8b, 0x6b, irq6B) +IRQ (0x8c, 0x6c, irq6C) +IRQ (0x8d, 0x6d, irq6D) +IRQ (0x8e, 0x6e, irq6E) +IRQ (0x8f, 0x6f, irq6F) + +IRQ (0x90, 0x70, irq70) +IRQ (0x91, 0x71, irq71) +IRQ (0x92, 0x72, irq72) +IRQ (0x93, 0x73, irq73) +IRQ (0x94, 0x74, irq74) +IRQ (0x95, 0x75, irq75) +IRQ (0x96, 0x76, irq76) +IRQ (0x97, 0x77, irq77) +IRQ (0x98, 0x78, irq78) +IRQ (0x99, 0x79, irq79) +IRQ (0x9a, 0x7a, irq7A) +IRQ (0x9b, 0x7b, irq7B) +IRQ (0x9c, 0x7c, irq7C) +IRQ (0x9d, 0x7d, irq7D) +IRQ (0x9e, 0x7e, irq7E) +IRQ (0x9f, 0x7f, irq7F) + +IRQ (0xa0, 0x80, irq80) +IRQ (0xa1, 0x81, irq81) +IRQ (0xa2, 0x82, irq82) +IRQ (0xa3, 0x83, irq83) +IRQ (0xa4, 0x84, irq84) +IRQ (0xa5, 0x85, irq85) +IRQ (0xa6, 0x86, irq86) +IRQ (0xa7, 0x87, irq87) +IRQ (0xa8, 0x88, irq88) +IRQ (0xa9, 0x89, irq89) +IRQ (0xaa, 0x8a, irq8A) +IRQ (0xab, 0x8b, irq8B) +IRQ (0xac, 0x8c, irq8C) +IRQ (0xad, 0x8d, irq8D) +IRQ (0xae, 0x8e, irq8E) +IRQ (0xaf, 0x8f, irq8F) + +IRQ (0xb0, 0x90, irq90) +IRQ (0xb1, 0x91, irq91) +IRQ (0xb2, 0x92, irq92) +IRQ (0xb3, 0x93, irq93) +IRQ (0xb4, 0x94, irq94) +IRQ (0xb5, 0x95, irq95) +IRQ (0xb6, 0x96, irq96) +IRQ (0xb7, 0x97, irq97) +IRQ (0xb8, 0x98, irq98) +IRQ (0xb9, 0x99, irq99) +IRQ (0xba, 0x9a, irq9A) +IRQ (0xbb, 0x9b, irq9B) +IRQ (0xbc, 0x9c, irq9C) +IRQ (0xbd, 0x9d, irq9D) +IRQ (0xbe, 0x9e, irq9E) +IRQ (0xbf, 0x9f, irq9F) + +IRQ (0xc0, 0xa0, irqA0) +IRQ (0xc1, 0xa1, irqA1) +IRQ (0xc2, 0xa2, irqA2) +IRQ (0xc3, 0xa3, irqA3) +IRQ (0xc4, 0xa4, irqA4) +IRQ (0xc5, 0xa5, irqA5) +IRQ (0xc6, 0xa6, irqA6) +IRQ (0xc7, 0xa7, irqA7) +IRQ (0xc8, 0xa8, irqA8) +IRQ (0xc9, 0xa9, irqA9) +IRQ (0xca, 0xaa, irqAA) +IRQ (0xcb, 0xab, irqAB) +IRQ (0xcc, 0xac, irqAC) +IRQ (0xcd, 0xad, irqAD) +IRQ (0xce, 0xae, irqAE) +IRQ (0xcf, 0xaf, irqAF) + +IRQ (0xd0, 0xb0, irqB0) +IRQ (0xd1, 0xb1, irqB1) +IRQ (0xd2, 0xb2, irqB2) +IRQ (0xd3, 0xb3, irqB3) +IRQ (0xd4, 0xb4, irqB4) +IRQ (0xd5, 0xb5, irqB5) +IRQ (0xd6, 0xb6, irqB6) +IRQ (0xd7, 0xb7, irqB7) +IRQ (0xd8, 0xb8, irqB8) +IRQ (0xd9, 0xb9, irqB9) +IRQ (0xda, 0xba, irqBA) +IRQ (0xdb, 0xbb, irqBB) +IRQ (0xdc, 0xbc, irqBC) +IRQ (0xdd, 0xbd, irqBD) +IRQ (0xde, 0xbe, irqBE) +IRQ (0xdf, 0xbf, irqBF) + + ISR (0xe7, isrAssert) ISR (0xec, isrTimer) diff --git a/src/kernel/interrupts.s b/src/kernel/interrupts.s index cea294c..d40ed90 100644 --- a/src/kernel/interrupts.s +++ b/src/kernel/interrupts.s @@ -1,84 +1,4 @@ -extern g_idtr -extern g_gdtr - -global idt_write -idt_write: - lidt [rel g_idtr] - ret - -global idt_load -idt_load: - sidt [rel g_idtr] - ret - -global gdt_write -gdt_write: - lgdt [rel g_gdtr] - mov ax, si ; second arg is data segment - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - push qword rdi ; first arg is code segment - lea rax, [rel .next] - push rax - o64 retf -.next: - ltr dx - ret - -global gdt_load -gdt_load: - sgdt [rel g_gdtr] - ret - -%macro push_all_and_segments 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi - - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - - mov ax, ds - push rax -%endmacro - -%macro pop_all_and_segments 0 - pop rax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax -%endmacro +%include "push_all.inc" extern isr_handler global isr_handler_prelude @@ -142,70 +62,3 @@ irq_handler_prelude: section .isrs %include "interrupt_isrs.inc" - -extern syscall_handler -syscall_handler_prelude: - push 0 ; ss, doesn't matter here - push rsp - pushf - push 0 ; cs, doesn't matter here - push rcx ; user rip - push 0 ; bogus interrupt - push 0 ; bogus errorcode - push_all_and_segments - - mov rdi, rsp - call syscall_handler - mov rsp, rax - - pop_all_and_segments - add rsp, 16 ; ignore bogus interrupt / error - pop rcx ; user rip - add rsp, 32 ; ignore cs, flags, rsp, ss - - o64 sysret - -global syscall_enable -syscall_enable: - ; IA32_EFER - set bit 0, syscall enable - mov rcx, 0xc0000080 - rdmsr - or rax, 0x1 - wrmsr - - ; IA32_STAR - cs for syscall - mov rcx, 0xc0000081 - mov rax, 0 ; not used - mov rdx, 0x00180008 ; GDT:3 (user code), GDT:1 (kernel code) - wrmsr - - ; IA32_LSTAR - RIP for syscall - mov rcx, 0xc0000082 - lea rax, [rel syscall_handler_prelude] - mov rdx, rax - shr rdx, 32 - wrmsr - - ; IA32_FMASK - FLAGS mask inside syscall - mov rcx, 0xc0000084 - mov rax, 0x200 - mov rdx, 0 - wrmsr - - ret - -extern load_process -global ramdisk_process_loader -ramdisk_process_loader: - - ; create_process already pushed a cpu_state onto the stack for us, this - ; acts both as the cpu_state parameter to load_process, and the saved - ; state for the following iretq - mov rdi, rax - mov rsi, rbx - call load_process - - pop_all_and_segments - add rsp, 16 ; because the ISRs add err/num - iretq - diff --git a/src/kernel/loader.s b/src/kernel/loader.s new file mode 100644 index 0000000..3849f4c --- /dev/null +++ b/src/kernel/loader.s @@ -0,0 +1,19 @@ +%include "push_all.inc" + +extern load_process + +global ramdisk_process_loader +ramdisk_process_loader: + + ; create_process already pushed a cpu_state onto the stack for us, this + ; acts both as the cpu_state parameter to load_process, and the saved + ; state for the following iretq + mov rdi, rax + mov rsi, rbx + call load_process + + pop_all_and_segments + add rsp, 16 ; because the ISRs add err/num + iretq + + diff --git a/src/kernel/push_all.inc b/src/kernel/push_all.inc new file mode 100644 index 0000000..57cd945 --- /dev/null +++ b/src/kernel/push_all.inc @@ -0,0 +1,48 @@ +%macro push_all_and_segments 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + mov ax, ds + push rax +%endmacro + +%macro pop_all_and_segments 0 + pop rax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +; vim: ft=asm diff --git a/src/kernel/syscall.s b/src/kernel/syscall.s new file mode 100644 index 0000000..109f9b0 --- /dev/null +++ b/src/kernel/syscall.s @@ -0,0 +1,52 @@ +%include "push_all.inc" + +global syscall_enable +syscall_enable: + ; IA32_EFER - set bit 0, syscall enable + mov rcx, 0xc0000080 + rdmsr + or rax, 0x1 + wrmsr + + ; IA32_STAR - cs for syscall + mov rcx, 0xc0000081 + mov rax, 0 ; not used + mov rdx, 0x00180008 ; GDT:3 (user code), GDT:1 (kernel code) + wrmsr + + ; IA32_LSTAR - RIP for syscall + mov rcx, 0xc0000082 + lea rax, [rel syscall_handler_prelude] + mov rdx, rax + shr rdx, 32 + wrmsr + + ; IA32_FMASK - FLAGS mask inside syscall + mov rcx, 0xc0000084 + mov rax, 0x200 + mov rdx, 0 + wrmsr + + ret + +extern syscall_handler +syscall_handler_prelude: + push 0 ; ss, doesn't matter here + push rsp + pushf + push 0 ; cs, doesn't matter here + push rcx ; user rip + push 0 ; bogus interrupt + push 0 ; bogus errorcode + push_all_and_segments + + mov rdi, rsp + call syscall_handler + mov rsp, rax + + pop_all_and_segments + add rsp, 16 ; ignore bogus interrupt / error + pop rcx ; user rip + add rsp, 32 ; ignore cs, flags, rsp, ss + + o64 sysret