aboutsummaryrefslogtreecommitdiff
path: root/kernel/main/smp_trampoline.S
diff options
context:
space:
mode:
authornthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
committernthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
commitc63f340d90800895f007de64b7d2d14624263331 (patch)
tree2c0849fa597dd6da831c8707b6f2603403778d7b /kernel/main/smp_trampoline.S
Created student weenix repository
Diffstat (limited to 'kernel/main/smp_trampoline.S')
-rw-r--r--kernel/main/smp_trampoline.S81
1 files changed, 81 insertions, 0 deletions
diff --git a/kernel/main/smp_trampoline.S b/kernel/main/smp_trampoline.S
new file mode 100644
index 0000000..9273f0f
--- /dev/null
+++ b/kernel/main/smp_trampoline.S
@@ -0,0 +1,81 @@
+#define CR0_PG 0x80000000
+#define CR0_PE 0x00000001
+
+#define CR4_PAE 0x00000020
+#define CR4_PGE 0x00000080
+
+#define PHYSADDR(x) (x - smp_initialization_start)
+
+# NOTE: THIS CODE REQUIRES THAT IT BE PLACED STARTING AT PHYSICAL ADDRESS 0x0
+
+.file "smp_trampoline.S"
+.global smp_initialization_start, smp_initialization_end
+
+smp_initialization_start:
+
+/* When we initialize a processor, it starts in 16-bit real mode */
+.code16
+.align 0x1000
+smp_processor_init:
+ cli
+
+ // enable PAE
+ mov $(CR4_PAE | CR4_PGE), %eax
+ mov %eax, %cr4
+
+ mov $PHYSADDR(pml4), %eax
+ mov %eax, %cr3
+
+ // enter long mode
+ mov $0xC0000080, %ecx
+ rdmsr
+ or $0x100, %eax
+ wrmsr
+
+ lgdt PHYSADDR(GDTPointer)
+
+ // Enable paging AND protection simultaneously
+ movl %cr0, %eax
+ or $(CR0_PG | CR0_PE), %eax
+ movl %eax, %cr0
+
+ ljmp $0x8, $PHYSADDR(smp_trampoline)
+
+.code64
+smp_trampoline:
+ movabsq $(0xffff880000000000 + PHYSADDR(stack_pointer)), %rsp
+ xor %rbp, %rbp
+ movabsq $smp_processor_entry, %rax
+ call *%rax
+
+
+.align 16
+GDT64:
+ GDTNull:
+ .quad 0
+ GDTKernelCode:
+ // base = 0x0, limit = 0x0
+ // flags: present, ring 0, executable, readable, 64bit
+ .word 0, 0
+ .byte 0, 0x9a, 0x20, 0
+ GDTEnd:
+ GDTPointer:
+ .word GDTEnd - GDT64 - 1 // size of gdt - 1
+ .long PHYSADDR(GDT64) // pointer to gdt
+
+.align 0x1000
+pml4: // maps first 1GB of RAM to both 0x0000000000000000 and 0xffff800000000000
+ .quad PHYSADDR(pdpt) + 3
+ .fill 255,8,0
+ .quad PHYSADDR(pdpt) + 3
+ .fill 15,8,0
+ .quad PHYSADDR(pdpt) + 3
+ .fill 239,8,0
+pdpt:
+ .quad 0x0000000000000083
+ .fill 511,8,0
+
+.skip 0x1000
+stack_pointer:
+
+smp_initialization_end: