IndigoOS/src/kernel/smp_trampoline.asm
2021-08-24 14:09:29 -05:00

141 lines
2.3 KiB
NASM

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