section .rodata invalid_idt: dq 0, 0 section .text extern flush_irqs %macro push32 1 sub rsp, 4 mov dword [rsp], %1 %endmacro extern gdt global common_spinup bits 64 common_spinup: cli lgdt [rel gdt] lidt [rel invalid_idt] lea rbx, [rel .reload_cs] push 0x28 push rbx retfq .reload_cs: mov eax, 0x30 mov ds, eax mov es, eax mov fs, eax mov gs, eax mov ss, eax push r8 push r9 push rcx push rdx push rsi push rdi call flush_irqs pop rdi pop rsi pop rdx pop rcx pop r9 pop r8 mov rbp, rsp sub esi, 4 jle .no_stack_args .push_stack_args: dec esi mov eax, [rbp + 8 + rsi*8] push32 eax test esi, esi jnz .push_stack_args .no_stack_args: push32 r9d push32 r8d push32 ecx push32 edx lea rbx, [rel .go_32] push 0x18 push rbx retfq bits 32 .go_32: mov eax, 0x20 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax xor eax, eax lldt ax mov eax, 0x00000011 mov cr0, eax mov ecx, 0xc0000080 xor eax, eax xor edx, edx wrmsr xor eax, eax mov cr4, eax mov cr3, eax ; Clear TSS busy bit and load TR with base 0, limit 0 sub esp, 8 sgdt [esp] mov eax, [esp + 2] add esp, 8 mov byte [eax + 0x3d], 0x89 mov ax, 0x38 ltr ax call edi section .note.GNU-stack noalloc noexec nowrite progbits