summaryrefslogtreecommitdiff
path: root/src/kernel/smp_trampoline.asm
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcspace.com>2021-08-24 14:09:29 -0500
committerBrett Weiland <brett_weiland@bpcspace.com>2021-08-24 14:09:29 -0500
commit9b22a6965579ea1867aea291d910c96f386b518b (patch)
treed06dbb9c4708f1cc713bcb115b32ff9bce4cf9b9 /src/kernel/smp_trampoline.asm
parentbad4b0e9bdfee336bfc1c23761408279eaec1558 (diff)
major backup 8.24.21
Diffstat (limited to 'src/kernel/smp_trampoline.asm')
-rw-r--r--src/kernel/smp_trampoline.asm140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/kernel/smp_trampoline.asm b/src/kernel/smp_trampoline.asm
new file mode 100644
index 0000000..f723aa6
--- /dev/null
+++ b/src/kernel/smp_trampoline.asm
@@ -0,0 +1,140 @@
+global smp_bootstrap_corecount;
+
+[bits 16]
+smp_trampoline:
+cli
+hlt
+hlt
+
+xor ax, ax
+mov ds, ax
+lgdt [.gdt_descriptor_p]
+mov eax, cr0
+or eax, 0x1
+mov cr0, eax ; now in long mode
+
+jmp 0x8:.smp_protected
+
+
+;________________________________________________________________________________________
+
+;TODO find how to use old gdt
+.gdt_start_p: ; we need to start with a null gdt
+dd 0
+dd 0
+
+.gdt_code_p:
+dw 0xffff
+dw 0x0000
+db 0x00
+db 10011010b
+db 11001111b
+db 0x0000
+
+.gdt_data_p:
+dw 0xffff
+dw 0x0000
+db 0x00
+db 10010010b
+db 11001111b
+db 0x0000
+
+.gdt_end_p:
+
+.gdt_descriptor_p:
+ dw .gdt_end_p - .gdt_start_p - 1
+dq .gdt_start_p
+
+SMP_PROTECTED_CODE_SEGMENT equ .gdt_code_p - .gdt_start_p
+SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p
+
+;________________________________________________________________________________________
+
+.smp_protected
+
+[bits 32]
+mov ax, SMP_PROTECTED_DATA_SEGMENT
+mov ds, ax
+mov ss, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+mov eax, 0x10000 ;TODO clarify _why_ this is a thing
+mov cr3, eax
+
+;setting up misc features
+mov eax, cr4
+; PAE, OSFXSR, OSXMMEXCPT
+or eax, 1 << 5 | 1 << 9 | 1 << 10
+mov cr4, eax
+
+
+;set NX and LME
+mov eax, 0x80000001
+cpuid
+and edx, 1 << 20
+shr edx, 9
+
+mov ecx, 0xc0000080
+rdmsr
+or eax, 1 << 8 | 1 << 11
+or eax, edx
+wrmsr
+
+;enable paging
+mov eax, cr0
+or eax, 1 << 31 | 1 << 0;
+and ax, ~(1 << 2)
+mov cr0, eax
+
+jmp SMP_LONG_CODE_SEGMENT:.counter
+
+;________________________________________________________________________________________
+
+[bits 64]
+;TODO do we really need all this?
+.gdt_start_l:
+;and now we set up a temporary GDT creating a 1:1 mapping
+dw 0xffff
+dw 0
+db 0 ;this is the invalid GDT
+db 0
+db 1
+db 0
+
+;now for the code GDT:
+.gdt_code_l:
+dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!)
+dw 0 ; base address 15:00
+db 0 ; base address 23:16
+db 10011010b
+db 00100000b
+db 0
+
+.gdt_data_l:
+dw 0
+dw 0
+db 0
+db 10010010b
+db 00100000b
+db 0
+
+.gdt_end_l: ; later calculates offset in defs below
+
+
+.descriptor_l:
+ dw .gdt_end_l - .gdt_start_l - 1
+dq .gdt_start_l
+
+SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l
+SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l
+
+.counter:
+mov rax, [smp_bootstrap_corecount]
+inc QWORD [rax]
+cli
+hlt
+;TODO set up stack; enter kernel
+
+smp_bootstrap_corecount: db 0