diff options
Diffstat (limited to 'src/platform')
-rw-r--r-- | src/platform/asm.h | 9 | ||||
-rw-r--r-- | src/platform/boot.s | 47 | ||||
-rw-r--r-- | src/platform/sysenter.s | 31 |
3 files changed, 87 insertions, 0 deletions
diff --git a/src/platform/asm.h b/src/platform/asm.h new file mode 100644 index 0000000..6f72617 --- /dev/null +++ b/src/platform/asm.h @@ -0,0 +1,9 @@ +#pragma once + +// boot.s +__attribute__((noreturn)) +void halt_cpu(); + +// sysenter.c +void sysexit(void (*fun)(), void *stack_top); +void sysenter_setup(); diff --git a/src/platform/boot.s b/src/platform/boot.s new file mode 100644 index 0000000..d5bfda5 --- /dev/null +++ b/src/platform/boot.s @@ -0,0 +1,47 @@ +.set MAGIC, 0x1BADB002 +.set FLAG_ALIGN, 1<<0 /* align modules on page boundaries */ +.set FLAG_MEMINFO, 1<<1 /* memory map */ +.set FLAGS, FLAG_ALIGN | FLAG_MEMINFO +.set CHECKSUM, -(MAGIC + FLAGS) + +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +/* a lil stack */ +.section .bss +.global stack_top +.type stack_top, @object +.align 16 +stack_bottom: +.skip 16384 +stack_top: + + +.section .text +.global _start +.type _start, @function +_start: + mov $stack_top, %esp + call kmain + +.global halt_cpu +.type halt_cpu, @function +halt_cpu: + cli +1: hlt + jmp 1b + +// temporary, will be moved to another file soon +.global change_cs +.type change_cs, @function +change_cs: + /* retf pops off the return address and code segment off the stack. + * it turns out that in the i386 cdecl calling convention they're in + * the correct place already. + */ + retf + +.size _start, . - _start diff --git a/src/platform/sysenter.s b/src/platform/sysenter.s new file mode 100644 index 0000000..270dc08 --- /dev/null +++ b/src/platform/sysenter.s @@ -0,0 +1,31 @@ +/* kernel/gdt.c */ +.set SEG_r0code, 1 +.set SEG_r3code, 3 +.set SEG_r3data, 4 + +.set IA32_SYSENTER_CS, 0x174 + +.section .text +.global sysexit +.type sysexit, @function +sysexit: + pop %ecx + pop %edx + + mov $(SEG_r3data << 3 | 3), %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + sysexit + + +.global sysenter_setup +.type sysenter_setup, @function +sysenter_setup: + xor %edx, %edx + mov $(SEG_r0code << 3), %eax + mov $IA32_SYSENTER_CS, %ecx + wrmsr + ret |