boot: Add EFISTUB and refactor boot protocols
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
.intel_syntax noprefix
|
||||
.text
|
||||
|
||||
.globl arch_enter_kernel
|
||||
.type arch_enter_kernel, @function
|
||||
.balign 16
|
||||
arch_enter_kernel:
|
||||
cli
|
||||
mov cr3, rdi
|
||||
jmp rsi
|
||||
.size arch_enter_kernel, . - arch_enter_kernel
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
constexpr uint64_t ARCH_HHDM_BASE = 0xffff'8000'0000'0000;
|
||||
constexpr uint64_t ARCH_HUGE_PAGE_SIZE = 0x20'0000;
|
||||
@@ -0,0 +1,11 @@
|
||||
loader_sources += files(
|
||||
'enter.S',
|
||||
'paging.c',
|
||||
)
|
||||
|
||||
loader_c_args += [
|
||||
'-mno-red-zone',
|
||||
'-masm=intel',
|
||||
]
|
||||
|
||||
loader_objcopy_format = 'elf64-x86-64'
|
||||
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
#include <bits/pmap.h>
|
||||
#include <x86_64/defs.h>
|
||||
#include "loader.h"
|
||||
#include "loader_arch.h"
|
||||
|
||||
static bool next_table(uint64_t* table, size_t index, uint64_t** out) {
|
||||
if (!(table[index] & ARCH_FLAG_PRESENT)) {
|
||||
uint64_t page;
|
||||
if (!loader_alloc(PHYS_RECLAIMABLE, PAGE_SIZE, &page))
|
||||
return false;
|
||||
table[index] = page | ARCH_FLAG_PRESENT | ARCH_FLAG_READ_WRITE;
|
||||
}
|
||||
*out = loader_ptr(table[index] & ARCH_PTE_ADDR_MASK);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool arch_check_cpu() {
|
||||
uint64_t cr4;
|
||||
asm volatile("mov %0, cr4" : "=r"(cr4));
|
||||
if (cr4 & CR4_LA57)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool arch_paging_map(uint64_t root, uint64_t virt, uint64_t phys, uint64_t size, uint64_t page_size) {
|
||||
const int leaf_level = page_size == ARCH_HUGE_PAGE_SIZE ? 1 : 0;
|
||||
|
||||
for (uint64_t off = 0; off < size; off += page_size) {
|
||||
const uint64_t va = virt + off;
|
||||
uint64_t* table = loader_ptr(root);
|
||||
for (int level = 3; level > leaf_level; level--) {
|
||||
if (!next_table(table, (va >> (12 + 9 * level)) & 0x1ff, &table))
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t entry = (phys + off) | ARCH_FLAG_PRESENT | ARCH_FLAG_READ_WRITE;
|
||||
if (leaf_level == 1)
|
||||
entry |= ARCH_FLAG_SIZE;
|
||||
table[(va >> (12 + 9 * leaf_level)) & 0x1ff] = entry;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user