stivale: Implement higher half returned addresses flag
This commit is contained in:
parent
07d9f7d7ee
commit
4bd3a540a8
@ -6,11 +6,13 @@
|
||||
__attribute__((noreturn)) void stivale_spinup_32(
|
||||
int bits, bool level5pg, uint32_t pagemap_top_lv,
|
||||
uint32_t entry_point_lo, uint32_t entry_point_hi,
|
||||
void *stivale_struct, uint32_t stack_lo, uint32_t stack_hi) {
|
||||
uint64_t entry_point =
|
||||
(uint64_t)entry_point_lo | ((uint64_t)entry_point_hi << 32);
|
||||
uint64_t stack =
|
||||
(uint64_t)stack_lo | ((uint64_t)stack_hi << 32);
|
||||
uint32_t stivale_struct_lo, uint32_t stivale_struct_hi,
|
||||
uint32_t stack_lo, uint32_t stack_hi) {
|
||||
uint64_t casted_to_64[] = {
|
||||
(uint64_t)stivale_struct_lo | ((uint64_t)stivale_struct_hi << 32),
|
||||
(uint64_t)entry_point_lo | ((uint64_t)entry_point_hi << 32),
|
||||
(uint64_t)stack_lo | ((uint64_t)stack_hi << 32)
|
||||
};
|
||||
|
||||
if (bits == 64) {
|
||||
if (level5pg) {
|
||||
@ -52,14 +54,15 @@ __attribute__((noreturn)) void stivale_spinup_32(
|
||||
|
||||
// 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 registers we use to store stack pointer and instruction
|
||||
// pointer
|
||||
// of the register that points to the 64-bit casted value array.
|
||||
"mov esi, esi\n\t"
|
||||
"mov ebx, ebx\n\t"
|
||||
"mov edi, edi\n\t"
|
||||
|
||||
// Move in 64-bit values
|
||||
"mov rdi, qword ptr [rsi + 0]\n\t"
|
||||
"mov rbx, qword ptr [rsi + 8]\n\t"
|
||||
"mov rsi, qword ptr [rsi + 16]\n\t"
|
||||
|
||||
// Let's pretend we push a return address
|
||||
"mov rsi, qword ptr [rsi]\n\t"
|
||||
"test rsi, rsi\n\t"
|
||||
"jz 1f\n\t"
|
||||
|
||||
@ -71,7 +74,7 @@ __attribute__((noreturn)) void stivale_spinup_32(
|
||||
"push rsi\n\t"
|
||||
"pushfq\n\t"
|
||||
"push 0x28\n\t"
|
||||
"push [rbx]\n\t"
|
||||
"push rbx\n\t"
|
||||
|
||||
"xor rax, rax\n\t"
|
||||
"xor rbx, rbx\n\t"
|
||||
@ -91,8 +94,7 @@ __attribute__((noreturn)) void stivale_spinup_32(
|
||||
"iretq\n\t"
|
||||
".code32\n\t"
|
||||
:
|
||||
: "a" (pagemap_top_lv), "b" (&entry_point),
|
||||
"D" (stivale_struct), "S" (&stack)
|
||||
: "a" (pagemap_top_lv), "S" (casted_to_64)
|
||||
: "memory"
|
||||
);
|
||||
} else if (bits == 32) {
|
||||
@ -100,13 +102,13 @@ __attribute__((noreturn)) void stivale_spinup_32(
|
||||
"cli\n\t"
|
||||
"cld\n\t"
|
||||
|
||||
"mov esp, dword ptr [esi]\n\t"
|
||||
"mov esp, esi\n\t"
|
||||
"push edi\n\t"
|
||||
"push 0\n\t"
|
||||
|
||||
"pushfd\n\t"
|
||||
"push 0x18\n\t"
|
||||
"push [ebx]\n\t"
|
||||
"push ebx\n\t"
|
||||
|
||||
"xor eax, eax\n\t"
|
||||
"xor ebx, ebx\n\t"
|
||||
@ -118,7 +120,9 @@ __attribute__((noreturn)) void stivale_spinup_32(
|
||||
|
||||
"iret\n\t"
|
||||
:
|
||||
: "b"(&entry_point), "D"(stivale_struct), "S"(&stack)
|
||||
: "D" ((uint32_t)casted_to_64[0]),
|
||||
"b" ((uint32_t)casted_to_64[1]),
|
||||
"S" ((uint32_t)casted_to_64[2])
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
@ -22,6 +22,10 @@
|
||||
#include <stivale/stivale.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
|
||||
#define REPORTED_ADDR(PTR) \
|
||||
((PTR) + ((stivale_hdr.flags & (1 << 3)) ? \
|
||||
(want_5lv ? 0xff00000000000000 : 0xffff800000000000) : 0))
|
||||
|
||||
struct stivale_struct stivale_struct = {0};
|
||||
|
||||
void stivale_load(char *config, char *cmdline) {
|
||||
@ -105,6 +109,9 @@ void stivale_load(char *config, char *cmdline) {
|
||||
panic("stivale: Section .stivalehdr is smaller than size of the struct.");
|
||||
}
|
||||
|
||||
bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
|
||||
pagemap_t pagemap = stivale_build_pagemap(want_5lv, false);
|
||||
|
||||
if (stivale_hdr.entry_point != 0)
|
||||
entry_point = stivale_hdr.entry_point;
|
||||
|
||||
@ -141,11 +148,11 @@ void stivale_load(char *config, char *cmdline) {
|
||||
if (!uri_open(&f, module_path))
|
||||
panic("Requested module with path \"%s\" not found!", module_path);
|
||||
|
||||
m->begin = (uint64_t)(size_t)freadall(&f, STIVALE_MMAP_KERNEL_AND_MODULES);
|
||||
m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(&f, STIVALE_MMAP_KERNEL_AND_MODULES));
|
||||
m->end = m->begin + f.size;
|
||||
m->next = 0;
|
||||
|
||||
*prev_mod_ptr = (uint64_t)(size_t)m;
|
||||
*prev_mod_ptr = REPORTED_ADDR((uint64_t)(size_t)m);
|
||||
prev_mod_ptr = &m->next;
|
||||
|
||||
print("stivale: Requested module %u:\n", i);
|
||||
@ -155,12 +162,20 @@ void stivale_load(char *config, char *cmdline) {
|
||||
print(" End: %X\n", m->end);
|
||||
}
|
||||
|
||||
stivale_struct.rsdp = (uint64_t)(size_t)acpi_get_rsdp();
|
||||
uint64_t rsdp = (uint64_t)(size_t)acpi_get_rsdp();
|
||||
|
||||
acpi_get_smbios((void **)&stivale_struct.smbios_entry_32,
|
||||
(void **)&stivale_struct.smbios_entry_64);
|
||||
if (rsdp)
|
||||
stivale_struct.rsdp = REPORTED_ADDR(rsdp);
|
||||
|
||||
stivale_struct.cmdline = (uint64_t)(size_t)cmdline;
|
||||
uint64_t smbios_entry_32 = 0, smbios_entry_64 = 0;
|
||||
acpi_get_smbios((void **)&smbios_entry_32, (void **)&smbios_entry_64);
|
||||
|
||||
if (smbios_entry_32)
|
||||
stivale_struct.smbios_entry_32 = REPORTED_ADDR(smbios_entry_32);
|
||||
if (smbios_entry_64)
|
||||
stivale_struct.smbios_entry_64 = REPORTED_ADDR(smbios_entry_64);
|
||||
|
||||
stivale_struct.cmdline = REPORTED_ADDR((uint64_t)(size_t)cmdline);
|
||||
|
||||
stivale_struct.epoch = time();
|
||||
print("stivale: Current epoch: %U\n", stivale_struct.epoch);
|
||||
@ -184,7 +199,7 @@ void stivale_load(char *config, char *cmdline) {
|
||||
(uint64_t)fbinfo.framebuffer_pitch * fbinfo.framebuffer_height,
|
||||
MEMMAP_FRAMEBUFFER, false, false, false, true);
|
||||
|
||||
stivale_struct.framebuffer_addr = (uint64_t)fbinfo.framebuffer_addr;
|
||||
stivale_struct.framebuffer_addr = REPORTED_ADDR((uint64_t)fbinfo.framebuffer_addr);
|
||||
stivale_struct.framebuffer_width = fbinfo.framebuffer_width;
|
||||
stivale_struct.framebuffer_height = fbinfo.framebuffer_height;
|
||||
stivale_struct.framebuffer_bpp = fbinfo.framebuffer_bpp;
|
||||
@ -209,9 +224,6 @@ void stivale_load(char *config, char *cmdline) {
|
||||
efi_exit_boot_services();
|
||||
#endif
|
||||
|
||||
bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1));
|
||||
pagemap_t pagemap = stivale_build_pagemap(want_5lv, false);
|
||||
|
||||
// Reserve 32K at 0x70000
|
||||
memmap_alloc_range(0x70000, 0x8000, MEMMAP_USABLE, true, true, false, false);
|
||||
|
||||
@ -219,10 +231,11 @@ void stivale_load(char *config, char *cmdline) {
|
||||
struct e820_entry_t *memmap = get_memmap(&memmap_entries);
|
||||
|
||||
stivale_struct.memory_map_entries = (uint64_t)memmap_entries;
|
||||
stivale_struct.memory_map_addr = (uint64_t)(size_t)memmap;
|
||||
stivale_struct.memory_map_addr = REPORTED_ADDR((uint64_t)(size_t)memmap);
|
||||
|
||||
stivale_spinup(bits, want_5lv, &pagemap,
|
||||
entry_point, &stivale_struct, stivale_hdr.stack);
|
||||
entry_point, REPORTED_ADDR((uint64_t)(uintptr_t)&stivale_struct),
|
||||
stivale_hdr.stack);
|
||||
}
|
||||
|
||||
pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null) {
|
||||
@ -286,11 +299,12 @@ extern symbol ImageBase;
|
||||
__attribute__((noreturn)) void stivale_spinup_32(
|
||||
int bits, bool level5pg, uint32_t pagemap_top_lv,
|
||||
uint32_t entry_point_lo, uint32_t entry_point_hi,
|
||||
void *stivale_struct, uint32_t stack_lo, uint32_t stack_hi);
|
||||
uint32_t stivale_struct_lo, uint32_t stivale_struct_hi,
|
||||
uint32_t stack_lo, uint32_t stack_hi);
|
||||
|
||||
__attribute__((noreturn)) void stivale_spinup(
|
||||
int bits, bool level5pg, pagemap_t *pagemap,
|
||||
uint64_t entry_point, void *stivale_struct, uint64_t stack) {
|
||||
uint64_t entry_point, uint64_t stivale_struct, uint64_t stack) {
|
||||
#if defined (bios)
|
||||
if (bits == 64) {
|
||||
// If we're going 64, we might as well call this BIOS interrupt
|
||||
@ -307,17 +321,17 @@ __attribute__((noreturn)) void stivale_spinup(
|
||||
pic_flush();
|
||||
|
||||
#if defined (uefi)
|
||||
do_32(stivale_spinup_32, 8,
|
||||
do_32(stivale_spinup_32, 9,
|
||||
bits, level5pg, (uint32_t)(uintptr_t)pagemap->top_level,
|
||||
(uint32_t)entry_point, (uint32_t)(entry_point >> 32),
|
||||
stivale_struct,
|
||||
(uint32_t)stivale_struct, (uint32_t)(stivale_struct >> 32),
|
||||
(uint32_t)stack, (uint32_t)(stack >> 32));
|
||||
#endif
|
||||
|
||||
#if defined (bios)
|
||||
stivale_spinup_32(bits, level5pg, (uint32_t)(uintptr_t)pagemap->top_level,
|
||||
(uint32_t)entry_point, (uint32_t)(entry_point >> 32),
|
||||
stivale_struct,
|
||||
(uint32_t)stivale_struct, (uint32_t)(stivale_struct >> 32),
|
||||
(uint32_t)stack, (uint32_t)(stack >> 32));
|
||||
#endif
|
||||
|
||||
|
@ -11,6 +11,6 @@ void stivale_load(char *config, char *cmdline);
|
||||
pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null);
|
||||
__attribute__((noreturn)) void stivale_spinup(
|
||||
int bits, bool level5pg, pagemap_t *pagemap,
|
||||
uint64_t entry_point, void *stivale_struct, uint64_t stack);
|
||||
uint64_t entry_point, uint64_t stivale_struct, uint64_t stack);
|
||||
|
||||
#endif
|
||||
|
@ -494,5 +494,5 @@ skip_modeset:;
|
||||
term_write("\e[2J\e[H", 7);
|
||||
|
||||
stivale_spinup(bits, level5pg && level5pg_requested, &pagemap,
|
||||
entry_point, &stivale2_struct, stivale2_hdr.stack);
|
||||
entry_point, (uint64_t)(uintptr_t)&stivale2_struct, stivale2_hdr.stack);
|
||||
}
|
||||
|
@ -12,12 +12,13 @@ struct stivale_header header = {
|
||||
.framebuffer_bpp = 0,
|
||||
.framebuffer_width = 0,
|
||||
.framebuffer_height = 0,
|
||||
.flags = 1,
|
||||
.flags = 1 | (1 << 3),
|
||||
.entry_point = (uint64_t)(uintptr_t)stivale_main
|
||||
};
|
||||
|
||||
void stivale_main(struct stivale_struct *info) {
|
||||
// Print some info.
|
||||
e9_printf("Stivale struct at %x", info);
|
||||
|
||||
e9_puts("Stivale information passed to the kernel:");
|
||||
e9_printf("Cmdline: %s", (char*)info->cmdline);
|
||||
e9_printf("Memory map at %x with contents:", info->memory_map_addr);
|
||||
@ -55,7 +56,7 @@ void stivale_main(struct stivale_struct *info) {
|
||||
struct stivale_module *modules = ((struct stivale_module *)(info->modules));
|
||||
for (size_t i = 0; i < info->module_count; i++) {
|
||||
struct stivale_module e = *modules;
|
||||
e9_printf("\tModule %d: [%x+%x] %s", i, e.begin, e.end, e.string);
|
||||
e9_printf("\tModule %d: [%x->%x] %s", i, e.begin, e.end, e.string);
|
||||
modules = (struct stivale_module *)e.next;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user