boot: Add EFISTUB and refactor boot protocols
This commit is contained in:
@@ -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