stivale2: Implement slide HHDM header tag
This commit is contained in:
parent
6bcbfe9b48
commit
01255704bd
@ -26,7 +26,7 @@
|
||||
|
||||
#define REPORTED_ADDR(PTR) \
|
||||
((PTR) + ((stivale_hdr.flags & (1 << 3)) ? \
|
||||
(want_5lv ? 0xff00000000000000 : 0xffff800000000000) : 0))
|
||||
direct_map_offset : 0))
|
||||
|
||||
bool stivale_load_by_anchor(void **_anchor, const char *magic,
|
||||
uint8_t *file, uint64_t filesize) {
|
||||
@ -185,6 +185,8 @@ bool stivale_load(char *config, char *cmdline) {
|
||||
|
||||
bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
|
||||
|
||||
uint64_t direct_map_offset = want_5lv ? 0xff00000000000000 : 0xffff800000000000;
|
||||
|
||||
if (stivale_hdr.entry_point != 0)
|
||||
entry_point = stivale_hdr.entry_point;
|
||||
|
||||
@ -329,7 +331,7 @@ bool stivale_load(char *config, char *cmdline) {
|
||||
|
||||
pagemap_t pagemap = {0};
|
||||
if (bits == 64)
|
||||
pagemap = stivale_build_pagemap(want_5lv, false, NULL, 0, false, 0, 0);
|
||||
pagemap = stivale_build_pagemap(want_5lv, false, NULL, 0, false, 0, 0, direct_map_offset);
|
||||
|
||||
// Reserve 32K at 0x70000 if possible
|
||||
if (!memmap_alloc_range(0x70000, 0x8000, MEMMAP_USABLE, true, false, false, false)) {
|
||||
@ -356,15 +358,17 @@ bool stivale_load(char *config, char *cmdline) {
|
||||
entry_point, REPORTED_ADDR((uint64_t)(uintptr_t)&stivale_struct),
|
||||
stivale_hdr.stack, false);
|
||||
|
||||
__builtin_unreachable();
|
||||
|
||||
fail:
|
||||
pmm_free(kernel, kernel_file_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null, struct elf_range *ranges, size_t ranges_count,
|
||||
bool want_fully_virtual, uint64_t physical_base, uint64_t virtual_base) {
|
||||
bool want_fully_virtual, uint64_t physical_base, uint64_t virtual_base,
|
||||
uint64_t direct_map_offset) {
|
||||
pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4);
|
||||
uint64_t higher_half_base = level5pg ? 0xff00000000000000 : 0xffff800000000000;
|
||||
|
||||
if (ranges_count == 0) {
|
||||
// Map 0 to 2GiB at 0xffffffff80000000
|
||||
@ -400,13 +404,13 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null, struct elf_range
|
||||
for (uint64_t i = 0; i < 0x200000; i += 0x1000) {
|
||||
if (!(i == 0 && unmap_null))
|
||||
map_page(pagemap, i, i, 0x03, false);
|
||||
map_page(pagemap, higher_half_base + i, i, 0x03, false);
|
||||
map_page(pagemap, direct_map_offset + i, i, 0x03, false);
|
||||
}
|
||||
|
||||
// Map 2MiB to 4GiB at higher half base and 0
|
||||
for (uint64_t i = 0x200000; i < 0x100000000; i += 0x200000) {
|
||||
map_page(pagemap, i, i, 0x03, true);
|
||||
map_page(pagemap, higher_half_base + i, i, 0x03, true);
|
||||
map_page(pagemap, direct_map_offset + i, i, 0x03, true);
|
||||
}
|
||||
|
||||
size_t _memmap_entries = memmap_entries;
|
||||
@ -434,7 +438,7 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null, struct elf_range
|
||||
for (uint64_t j = 0; j < aligned_length; j += 0x200000) {
|
||||
uint64_t page = aligned_base + j;
|
||||
map_page(pagemap, page, page, 0x03, true);
|
||||
map_page(pagemap, higher_half_base + page, page, 0x03, true);
|
||||
map_page(pagemap, direct_map_offset + page, page, 0x03, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,8 @@ bool stivale_load(char *config, char *cmdline);
|
||||
bool stivale_load_by_anchor(void **_anchor, const char *magic,
|
||||
uint8_t *file, uint64_t filesize);
|
||||
pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null, struct elf_range *ranges, size_t ranges_count,
|
||||
bool want_fully_virtual, uint64_t physical_base, uint64_t virtual_base);
|
||||
bool want_fully_virtual, uint64_t physical_base, uint64_t virtual_base,
|
||||
uint64_t direct_map_offset);
|
||||
__attribute__((noreturn)) void stivale_spinup(
|
||||
int bits, bool level5pg, pagemap_t *pagemap,
|
||||
uint64_t entry_point, uint64_t stivale_struct, uint64_t stack,
|
||||
|
@ -25,10 +25,11 @@
|
||||
#include <pxe/tftp.h>
|
||||
#include <drivers/edid.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/rand.h>
|
||||
|
||||
#define REPORTED_ADDR(PTR) \
|
||||
((PTR) + ((stivale2_hdr.flags & (1 << 1)) ? \
|
||||
(want_5lv ? 0xff00000000000000 : 0xffff800000000000) : 0))
|
||||
direct_map_offset : 0))
|
||||
|
||||
struct stivale2_struct stivale2_struct = {0};
|
||||
|
||||
@ -232,6 +233,19 @@ failed_to_load_header_section:
|
||||
|
||||
bool want_5lv = (get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_5LV_PAGING_ID) ? true : false) && level5pg;
|
||||
|
||||
uint64_t direct_map_offset = want_5lv ? 0xff00000000000000 : 0xffff800000000000;
|
||||
|
||||
{
|
||||
struct stivale2_header_tag_slide_hhdm *slt = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_SLIDE_HHDM_ID);
|
||||
if (slt != NULL) {
|
||||
if (slt->alignment % 0x200000 != 0 || slt->alignment == 0) {
|
||||
panic("stivale2: Requested HHDM slide alignment is not a multiple of 2MiB");
|
||||
}
|
||||
|
||||
direct_map_offset += (rand64() & ~(slt->alignment - 1)) & 0xffffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
if (stivale2_hdr.entry_point != 0)
|
||||
entry_point = stivale2_hdr.entry_point;
|
||||
|
||||
@ -624,6 +638,18 @@ have_tm_tag:;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Create HHDM struct tag
|
||||
//////////////////////////////////////////////
|
||||
{
|
||||
struct stivale2_struct_tag_hhdm *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_hhdm));
|
||||
tag->tag.identifier = STIVALE2_STRUCT_TAG_HHDM_ID;
|
||||
|
||||
tag->addr = direct_map_offset;
|
||||
|
||||
append_tag(&stivale2_struct, (struct stivale2_tag *)tag);
|
||||
}
|
||||
|
||||
#if bios == 1
|
||||
//////////////////////////////////////////////
|
||||
// Create PXE struct tag
|
||||
@ -693,7 +719,8 @@ have_tm_tag:;
|
||||
pagemap = stivale_build_pagemap(want_5lv, unmap_null,
|
||||
want_pmrs ? ranges : NULL,
|
||||
want_pmrs ? ranges_count : 0,
|
||||
want_fully_virtual, physical_base, virtual_base);
|
||||
want_fully_virtual, physical_base, virtual_base,
|
||||
direct_map_offset);
|
||||
|
||||
#if uefi == 1
|
||||
efi_exit_boot_services();
|
||||
@ -762,11 +789,11 @@ have_tm_tag:;
|
||||
if (verbose) {
|
||||
print("stivale2: Generated tags:\n");
|
||||
struct stivale2_tag *taglist =
|
||||
(void*)(uintptr_t)(stivale2_struct.tags & (uint64_t)0xffffffff);
|
||||
(void*)(uintptr_t)(stivale2_struct.tags - ((stivale2_hdr.flags & (1 << 1)) ? direct_map_offset : 0));
|
||||
for (size_t i = 0; ; i++) {
|
||||
print(" Tag #%u ID: %X\n", i, taglist->identifier);
|
||||
if (taglist->next) {
|
||||
taglist = (void*)(uintptr_t)(taglist->next & (uint64_t)0xffffffff);
|
||||
taglist = (void*)(uintptr_t)(taglist->next - ((stivale2_hdr.flags & (1 << 1)) ? direct_map_offset : 0));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -782,6 +809,8 @@ have_tm_tag:;
|
||||
REPORTED_ADDR((uint64_t)(uintptr_t)&stivale2_struct),
|
||||
stivale2_hdr.stack, want_pmrs);
|
||||
|
||||
__builtin_unreachable();
|
||||
|
||||
fail:
|
||||
pmm_free(kernel, kernel_file_size);
|
||||
return false;
|
||||
|
@ -7,10 +7,19 @@ typedef uint8_t stack[4096];
|
||||
static stack stacks[64] = {0};
|
||||
void stivale2_main(struct stivale2_struct *info);
|
||||
|
||||
struct stivale2_header_tag_slide_hhdm slide_hhdm = {
|
||||
.tag = {
|
||||
.identifier = STIVALE2_HEADER_TAG_SLIDE_HHDM_ID,
|
||||
.next = 0
|
||||
},
|
||||
.flags = 0,
|
||||
.alignment = 0x10000000
|
||||
};
|
||||
|
||||
struct stivale2_header_tag_terminal terminal_request = {
|
||||
.tag = {
|
||||
.identifier = STIVALE2_HEADER_TAG_TERMINAL_ID,
|
||||
.next = 0
|
||||
.next = (uint64_t)&slide_hhdm
|
||||
},
|
||||
.flags = 0
|
||||
};
|
||||
@ -204,6 +213,11 @@ void stivale2_main(struct stivale2_struct *info) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STIVALE2_STRUCT_TAG_HHDM_ID: {
|
||||
struct stivale2_struct_tag_hhdm *t = (struct stivale2_struct_tag_hhdm *)tag;
|
||||
e9_printf("Higher half direct map at: %x", t->addr);
|
||||
break;
|
||||
}
|
||||
case STIVALE2_STRUCT_TAG_KERNEL_BASE_ADDRESS_ID: {
|
||||
struct stivale2_struct_tag_kernel_base_address *t = (void *)tag;
|
||||
e9_puts("Kernel base address:");
|
||||
|
Loading…
x
Reference in New Issue
Block a user