141 lines
2.3 KiB
NASM
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
|