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