rulimine/stage23/protos/bootboot.32.c
2021-11-08 07:06:32 +01:00

90 lines
2.4 KiB
C

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <mm/vmm.h>
__attribute__((noreturn)) void bootboot_spinup_32(
uint32_t pagemap_top_lv,
uint32_t entry_point_lo, uint32_t entry_point_hi,
uint32_t stack_lo, uint32_t stack_hi) {
uint64_t casted_to_64[] = {
(uint64_t)entry_point_lo | ((uint64_t)entry_point_hi << 32),
(uint64_t)stack_lo | ((uint64_t)stack_hi << 32)
};
asm volatile (
"cld\n\t"
"movl %%eax, %%cr3\n\t"
"movl %%cr4, %%eax\n\t"
"btsl $5, %%eax\n\t"
"movl %%eax, %%cr4\n\t"
"movl $0xc0000080, %%ecx\n\t"
"rdmsr\n\t"
"btsl $8, %%eax\n\t"
"wrmsr\n\t"
"movl %%cr0, %%eax\n\t"
"btsl $31, %%eax\n\t"
"movl %%eax, %%cr0\n\t"
"call 1f\n\t"
"1: popl %%eax\n\t"
"addl $8, %%eax\n\t"
"pushl $0x28\n\t"
"pushl %%eax\n\t"
"lret\n\t"
".code64\n\t"
"movl $0x30, %%eax\n\t"
"movl %%eax, %%ds\n\t"
"movl %%eax, %%es\n\t"
"movl %%eax, %%fs\n\t"
"movl %%eax, %%gs\n\t"
"movl %%eax, %%ss\n\t"
// Since we don't really know what is now present in the upper
// 32 bits of the 64 bit registers, clear up the upper bits
// of the register that points to the 64-bit casted value array.
"movl %%esi, %%esi\n\t"
// Move in 64-bit values
"movq 0x00(%%rsi), %%rbx\n\t"
"movq 0x08(%%rsi), %%rsi\n\t"
// Let's pretend we push a return address
"testq %%rsi, %%rsi\n\t"
"jz 1f\n\t"
"subq $8, %%rsi\n\t"
"movq $0, (%%rsi)\n\t"
"1:\n\t"
"pushq $0x30\n\t"
"pushq %%rsi\n\t"
"pushfq\n\t"
"pushq $0x28\n\t"
"pushq %%rbx\n\t"
"xorl %%eax, %%eax\n\t"
"xorl %%ebx, %%ebx\n\t"
"xorl %%ecx, %%ecx\n\t"
"xorl %%edx, %%edx\n\t"
"xorl %%edi, %%edi\n\t"
"xorl %%esi, %%esi\n\t"
"xorl %%ebp, %%ebp\n\t"
"xorq %%r8, %%r8\n\t"
"xorq %%r9, %%r9\n\t"
"xorq %%r10, %%r10\n\t"
"xorq %%r11, %%r11\n\t"
"xorq %%r12, %%r12\n\t"
"xorq %%r13, %%r13\n\t"
"xorq %%r14, %%r14\n\t"
"xorq %%r15, %%r15\n\t"
"iretq\n\t"
".code32\n\t"
:
: "a" (pagemap_top_lv), "S" (casted_to_64)
: "memory"
);
__builtin_unreachable();
}