From 746d0ad529c2a72c31fb149c3450242874e8cfb3 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 14 Jun 2022 03:56:30 +0200 Subject: [PATCH] protos: Drop stivale and stivale2 support --- .gitignore | 1 - CONFIG.md | 17 +- GNUmakefile.in | 9 +- README.md | 1 - autogen.sh | 1 - common/GNUmakefile | 1 - common/entry.s2.c | 2 - common/menu.c | 12 +- common/protos/limine.32.c | 119 +++ common/protos/limine.c | 172 +++- .../{stivale2_rt.asm32u => limine_rt.asm32u} | 20 +- .../{stivale2_rt.asmb => limine_rt.asmb} | 20 +- common/protos/stivale.32.c | 156 ---- common/protos/stivale.c | 521 ----------- common/protos/stivale.h | 22 - common/protos/stivale2.c | 856 ------------------ common/protos/stivale2.h | 8 - test/GNUmakefile | 5 +- test/e9print.c | 6 +- test/e9print.h | 2 +- test/limine-fwcfg.cfg | 5 +- test/limine.c | 4 +- test/limine.cfg | 26 - test/linker.ld | 11 +- test/stivale.c | 68 -- test/stivale2.c | 281 ------ 26 files changed, 306 insertions(+), 2040 deletions(-) create mode 100644 common/protos/limine.32.c rename common/protos/{stivale2_rt.asm32u => limine_rt.asm32u} (84%) rename common/protos/{stivale2_rt.asmb => limine_rt.asmb} (81%) delete mode 100644 common/protos/stivale.32.c delete mode 100644 common/protos/stivale.c delete mode 100644 common/protos/stivale.h delete mode 100644 common/protos/stivale2.c delete mode 100644 common/protos/stivale2.h delete mode 100644 test/stivale.c delete mode 100644 test/stivale2.c diff --git a/.gitignore b/.gitignore index 16ae6831..ca746723 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ /bochsout.txt /bx_enh_dbg.ini /.vscode -/stivale /test_image !/common/font.bin /configure diff --git a/CONFIG.md b/CONFIG.md index 834e5280..f741f1aa 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -97,7 +97,7 @@ Editor control options. *Locally assignable (non protocol specific)* keys are: * `COMMENT` - An optional comment string that will be displayed by the bootloader on the menu when an entry is selected. -* `PROTOCOL` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `limine`, `stivale`, `stivale2`, `chainload`, `multiboot` or `multiboot1` and `multiboot2`. If the protocol is omitted, Limine will try to autodetect it, following this list of protocols, in this order: `stivale2 -> stivale1 -> multiboot2 -> multiboot1 -> limine -> linux -> failure`. +* `PROTOCOL` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `limine`, `chainload`, `multiboot` or `multiboot1` and `multiboot2`. If the protocol is omitted, Limine will try to autodetect it, following this list of protocols, in this order: `multiboot2 -> multiboot1 -> limine -> linux -> failure`. * `CMDLINE` - The command line string to be passed to the kernel. Can be omitted. * `KERNEL_CMDLINE` - Alias of `CMDLINE`. @@ -128,21 +128,6 @@ Editor control options. * Chainload protocol on UEFI: * `IMAGE_PATH` - URI of the EFI application to chainload. * `RESOLUTION` - The resolution to be used. This setting takes the form of `xx`. If the resolution is not available, Limine will pick another one automatically. Omitting `` will default to 32. -* stivale and stivale2 protocols: - * `KERNEL_PATH` - The URI path of the kernel. - * `MODULE_PATH` - The URI path to a module. - * `MODULE_STRING` - A string to be passed to a module. - - **Note:** One can define these 2 last variable multiple times to specify multiple - modules. - The entries will be matched in order. E.g.: The 1st module path entry will be matched - to the 1st module string entry that appear, and so on. - - **Note**: If `MODULE_STRING` is not specified for an entry, the `MODULE_STRING` will default to the `MODULE_PATH`. - - * `RESOLUTION` - The resolution to be used should the kernel request a graphical framebuffer. This setting takes the form of `xx` and *overrides* any resolution requested by the kernel, or automatic resolution requests. If the resolution is not available, Limine will pick another one automatically. Omitting `` will default to 32. - * `KASLR` - For relocatable kernels, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default. - * `TEXTMODE` - If set to `yes`, prefer text mode if the kernel has no video mode requirements. (Only for stivale2) * Chainload protocol on BIOS: * `DRIVE` - The 1-based BIOS drive to chainload, if omitted, assume boot drive. * `PARTITION` - The 1-based BIOS partition to chainload, if omitted, chainload drive (MBR). diff --git a/GNUmakefile.in b/GNUmakefile.in index 6586fa3c..1e5b65c8 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -199,7 +199,6 @@ dist: cd '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)" && NOCONFIGURE=yes ./autogen.sh rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/freestanding_headers/.git" rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/reduced-gnu-efi/.git" - rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/stivale/.git" rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/.git" rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/autom4te.cache" rm -rf '$(call SHESCAPE,$(BUILDDIR))'/"limine-$(LIMINE_VERSION)/test" @@ -215,10 +214,10 @@ distclean: clean .PHONY: maintainer-clean maintainer-clean: distclean - cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf freestanding_headers stivale reduced-gnu-efi configure build-aux *'~' autom4te.cache *.tar.xz *.tar.gz + cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf freestanding_headers reduced-gnu-efi configure build-aux *'~' autom4te.cache *.tar.xz *.tar.gz .PHONY: common-uefi64 -common-uefi64: $(call MKESCAPE,$(SRCDIR))/stivale +common-uefi64: $(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' all TARGET=uefi64 BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-uefi64' .PHONY: common-uefi64-clean @@ -226,7 +225,7 @@ common-uefi64-clean: $(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' clean TARGET=uefi64 BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-uefi64' .PHONY: common-uefi32 -common-uefi32: $(call MKESCAPE,$(SRCDIR))/stivale +common-uefi32: $(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' all TARGET=uefi32 BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-uefi32' .PHONY: common-uefi32-clean @@ -234,7 +233,7 @@ common-uefi32-clean: $(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' clean TARGET=uefi32 BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-uefi32' .PHONY: common-bios -common-bios: $(call MKESCAPE,$(SRCDIR))/stivale +common-bios: $(MAKE) -C '$(call SHESCAPE,$(SRCDIR))/common' all TARGET=bios BUILDDIR='$(call SHESCAPE,$(BUILDDIR))/common-bios' .PHONY: common-bios-clean diff --git a/README.md b/README.md index 94d3ba6b..d5884e8a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,6 @@ as the reference implementation for the [Limine boot protocol](/PROTOCOL.md). ### Supported boot protocols * Linux * [Limine](/PROTOCOL.md) -* stivale and stivale2 (see [their specifications](https://github.com/stivale) for details) * Multiboot 1 * Multiboot 2 * Chainloading diff --git a/autogen.sh b/autogen.sh index 7fa7dc5a..4baf2368 100755 --- a/autogen.sh +++ b/autogen.sh @@ -10,7 +10,6 @@ test -z "$srcdir" && srcdir=. cd "$srcdir" [ -d freestanding_headers ] || git clone https://github.com/mintsuki/freestanding_headers.git -[ -d stivale ] || git clone https://github.com/stivale/stivale.git [ -d reduced-gnu-efi ] || git clone https://github.com/limine-bootloader/reduced-gnu-efi.git automake_libdir="$(automake --print-libdir)" diff --git a/common/GNUmakefile b/common/GNUmakefile index e12bc1f8..9cad8842 100644 --- a/common/GNUmakefile +++ b/common/GNUmakefile @@ -67,7 +67,6 @@ override INTERNAL_CFLAGS := \ -I'$(call SHESCAPE,$(BUILDDIR))/..' \ -I. \ -I.. \ - -I../stivale \ -I'$(call SHESCAPE,$(BUILDDIR))/tinf' ifeq ($(TARGET), bios) diff --git a/common/entry.s2.c b/common/entry.s2.c index 14d48479..d13029f0 100644 --- a/common/entry.s2.c +++ b/common/entry.s2.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/common/menu.c b/common/menu.c index 676b5bee..2e294235 100644 --- a/common/menu.c +++ b/common/menu.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include @@ -917,8 +915,6 @@ noreturn void boot(char *config) { if (proto == NULL) { printv("PROTOCOL not specified, using autodetection...\n"); autodetect: - stivale2_load(config, cmdline); - stivale_load(config, cmdline); multiboot2_load(config, cmdline); multiboot1_load(config, cmdline); limine_load(config, cmdline); @@ -928,10 +924,10 @@ autodetect: bool ret = true; - if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale")) { - ret = stivale_load(config, cmdline); - } else if (!strcmp(proto, "stivale2")) { - ret = stivale2_load(config, cmdline); + if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale") || !strcmp(proto, "stivale2")) { + print("The stivale and stivale2 protocols is no longer supported as of Limine 4.x\n"); + print("Please notify kernel maintainers to move to the Limine boot protocol or\n"); + print("roll back to Limine 3.x.\n\n"); } else if (!strcmp(proto, "limine")) { ret = limine_load(config, cmdline); } else if (!strcmp(proto, "linux")) { diff --git a/common/protos/limine.32.c b/common/protos/limine.32.c new file mode 100644 index 00000000..a4614580 --- /dev/null +++ b/common/protos/limine.32.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include + +noreturn void limine_spinup_32( + bool level5pg, uint32_t pagemap_top_lv, + uint32_t entry_point_lo, uint32_t entry_point_hi, + uint32_t stack_lo, uint32_t stack_hi, + uint32_t local_gdt) { + 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), + (uint64_t)local_gdt + }; + + // Enable NX + asm volatile ( + "movl $0xc0000080, %%ecx\n\t" + "rdmsr\n\t" + "btsl $11, %%eax\n\t" + "wrmsr\n\t" + ::: "eax", "ecx", "edx", "memory" + ); + + if (level5pg) { + // Enable CR4.LA57 + asm volatile ( + "movl %%cr4, %%eax\n\t" + "btsl $12, %%eax\n\t" + "movl %%eax, %%cr4\n\t" + ::: "eax", "memory" + ); + } + + // Enable WP + asm volatile ( + "movl %%cr0, %%eax\n\t" + "btsl $16, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + ::: "eax", "memory" + ); + + 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 0x10(%%rsi), %%rax\n\t" + "movq 0x08(%%rsi), %%rsi\n\t" + + // Load 64 bit GDT + "lgdt (%%rax)\n\t" + + // Let's pretend we push a return address + "subq $8, %%rsi\n\t" + "movq $0, (%%rsi)\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 %%esi, %%esi\n\t" + "xorl %%edi, %%edi\n\t" + "xorl %%ebp, %%ebp\n\t" + "xorl %%r8d, %%r8d\n\t" + "xorl %%r9d, %%r9d\n\t" + "xorl %%r10d, %%r10d\n\t" + "xorl %%r11d, %%r11d\n\t" + "xorl %%r12d, %%r12d\n\t" + "xorl %%r13d, %%r13d\n\t" + "xorl %%r14d, %%r14d\n\t" + "xorl %%r15d, %%r15d\n\t" + + "iretq\n\t" + ".code32\n\t" + : + : "a" (pagemap_top_lv), "S" (casted_to_64) + : "memory" + ); + + __builtin_unreachable(); +} diff --git a/common/protos/limine.c b/common/protos/limine.c index b66d614c..f6c2f3e7 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include #include @@ -21,9 +19,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -35,6 +33,132 @@ #define MAX_REQUESTS 128 #define MAX_MEMMAP 256 +pagemap_t build_pagemap(bool level5pg, struct elf_range *ranges, size_t ranges_count, + uint64_t physical_base, uint64_t virtual_base, + uint64_t direct_map_offset) { + pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4); + + if (ranges_count == 0) { + // Map 0 to 2GiB at 0xffffffff80000000 + for (uint64_t i = 0; i < 0x80000000; i += 0x40000000) { + map_page(pagemap, 0xffffffff80000000 + i, i, 0x03, Size1GiB); + } + } else { + for (size_t i = 0; i < ranges_count; i++) { + uint64_t virt = ranges[i].base; + uint64_t phys; + + if (virt & ((uint64_t)1 << 63)) { + phys = physical_base + (virt - virtual_base); + } else { + panic(false, "limine: Protected memory ranges are only supported for higher half kernels"); + } + + uint64_t pf = VMM_FLAG_PRESENT | + (ranges[i].permissions & ELF_PF_X ? 0 : VMM_FLAG_NOEXEC) | + (ranges[i].permissions & ELF_PF_W ? VMM_FLAG_WRITE : 0); + + for (uint64_t j = 0; j < ranges[i].length; j += 0x1000) { + map_page(pagemap, virt + j, phys + j, pf, Size4KiB); + } + } + } + + // Sub 2MiB mappings + for (uint64_t i = 0; i < 0x200000; i += 0x1000) { + if (i != 0) { + map_page(pagemap, i, i, 0x03, Size4KiB); + } + map_page(pagemap, direct_map_offset + i, i, 0x03, Size4KiB); + } + + // Map 2MiB to 4GiB at higher half base and 0 + // + // NOTE: We cannot just directly map from 2MiB to 4GiB with 1GiB + // pages because if you do the math. + // + // start = 0x200000 + // end = 0x40000000 + // + // pages_required = (end - start) / (4096 * 512 * 512) + // + // So we map 2MiB to 1GiB with 2MiB pages and then map the rest + // with 1GiB pages :^) + for (uint64_t i = 0x200000; i < 0x40000000; i += 0x200000) { + map_page(pagemap, i, i, 0x03, Size2MiB); + map_page(pagemap, direct_map_offset + i, i, 0x03, Size2MiB); + } + + for (uint64_t i = 0x40000000; i < 0x100000000; i += 0x40000000) { + map_page(pagemap, i, i, 0x03, Size1GiB); + map_page(pagemap, direct_map_offset + i, i, 0x03, Size1GiB); + } + + size_t _memmap_entries = memmap_entries; + struct e820_entry_t *_memmap = + ext_mem_alloc(_memmap_entries * sizeof(struct e820_entry_t)); + for (size_t i = 0; i < _memmap_entries; i++) + _memmap[i] = memmap[i]; + + // Map any other region of memory from the memmap + for (size_t i = 0; i < _memmap_entries; i++) { + uint64_t base = _memmap[i].base; + uint64_t length = _memmap[i].length; + uint64_t top = base + length; + + if (base < 0x100000000) + base = 0x100000000; + + if (base >= top) + continue; + + uint64_t aligned_base = ALIGN_DOWN(base, 0x40000000); + uint64_t aligned_top = ALIGN_UP(top, 0x40000000); + uint64_t aligned_length = aligned_top - aligned_base; + + for (uint64_t j = 0; j < aligned_length; j += 0x40000000) { + uint64_t page = aligned_base + j; + map_page(pagemap, page, page, 0x03, Size1GiB); + map_page(pagemap, direct_map_offset + page, page, 0x03, Size1GiB); + } + } + + return pagemap; +} + +#if uefi == 1 +extern symbol ImageBase; +#endif + +extern symbol limine_spinup_32; + +static noreturn void spinup(bool level5pg, pagemap_t *pagemap, + uint64_t entry_point, uint64_t stack, + uint32_t local_gdt) { +#if bios == 1 + // If we're going 64, we might as well call this BIOS interrupt + // to tell the BIOS that we are entering Long Mode, since it is in + // the specification. + struct rm_regs r = {0}; + r.eax = 0xec00; + r.ebx = 0x02; // Long mode only + rm_int(0x15, &r, &r); +#endif + + vmm_assert_nx(); + + pic_mask_all(); + io_apic_mask_all(); + + irq_flush_type = IRQ_PIC_APIC_FLUSH; + + common_spinup(limine_spinup_32, 7, + level5pg, (uint32_t)(uintptr_t)pagemap->top_level, + (uint32_t)entry_point, (uint32_t)(entry_point >> 32), + (uint32_t)stack, (uint32_t)(stack >> 32), + local_gdt); +} + static uint64_t physical_base, virtual_base, slide, direct_map_offset; static size_t requests_count; static void **requests; @@ -111,11 +235,11 @@ static void *_get_request(uint64_t id[4]) { #define FEAT_END } while (0); #if defined (__i386__) -extern symbol stivale2_term_write_entry; -extern void *stivale2_rt_stack; -extern uint64_t stivale2_term_callback_ptr; -extern uint64_t stivale2_term_write_ptr; -void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); +extern symbol limine_term_write_entry; +void *limine_rt_stack = NULL; +uint64_t limine_term_callback_ptr = 0; +uint64_t limine_term_write_ptr = 0; +void limine_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); #endif static void term_write_shim(uint64_t context, uint64_t buf, uint64_t count) { @@ -505,8 +629,8 @@ FEAT_START if (terminal_request->callback != 0) { #if defined (__i386__) - term_callback = stivale2_term_callback; - stivale2_term_callback_ptr = terminal_request->callback; + term_callback = limine_term_callback; + limine_term_callback_ptr = terminal_request->callback; #elif defined (__x86_64__) term_callback = (void *)terminal_request->callback; #endif @@ -515,12 +639,12 @@ FEAT_START term_arg = reported_addr(terminal); #if defined (__i386__) - if (stivale2_rt_stack == NULL) { - stivale2_rt_stack = ext_mem_alloc(16384) + 16384; + if (limine_rt_stack == NULL) { + limine_rt_stack = ext_mem_alloc(16384) + 16384; } - stivale2_term_write_ptr = (uintptr_t)term_write_shim; - terminal_response->write = (uintptr_t)(void *)stivale2_term_write_entry; + limine_term_write_ptr = (uintptr_t)term_write_shim; + terminal_response->write = (uintptr_t)(void *)limine_term_write_entry; #elif defined (__x86_64__) terminal_response->write = (uintptr_t)term_write_shim; #endif @@ -571,8 +695,8 @@ FEAT_START if (terminal_request->callback != 0) { #if defined (__i386__) - term_callback = stivale2_term_callback; - stivale2_term_callback_ptr = terminal_request->callback; + term_callback = limine_term_callback; + limine_term_callback_ptr = terminal_request->callback; #elif defined (__x86_64__) term_callback = (void *)terminal_request->callback; #endif @@ -581,12 +705,12 @@ FEAT_START term_arg = reported_addr(terminal); #if defined (__i386__) - if (stivale2_rt_stack == NULL) { - stivale2_rt_stack = ext_mem_alloc(16384) + 16384; + if (limine_rt_stack == NULL) { + limine_rt_stack = ext_mem_alloc(16384) + 16384; } - stivale2_term_write_ptr = (uintptr_t)term_write_shim; - terminal_response->write = (uintptr_t)(void *)stivale2_term_write_entry; + limine_term_write_ptr = (uintptr_t)term_write_shim; + terminal_response->write = (uintptr_t)(void *)limine_term_write_entry; #elif defined (__x86_64__) terminal_response->write = (uintptr_t)term_write_shim; #endif @@ -744,8 +868,8 @@ FEAT_END void *stack = ext_mem_alloc(stack_size) + stack_size; pagemap_t pagemap = {0}; - pagemap = stivale_build_pagemap(want_5lv, true, ranges, ranges_count, true, - physical_base, virtual_base, direct_map_offset); + pagemap = build_pagemap(want_5lv, ranges, ranges_count, + physical_base, virtual_base, direct_map_offset); #if uefi == 1 efi_exit_boot_services(); @@ -866,8 +990,8 @@ FEAT_END term_runtime = true; - stivale_spinup(64, want_5lv, &pagemap, entry_point, 0, - reported_addr(stack), true, true, (uintptr_t)local_gdt); + spinup(want_5lv, &pagemap, entry_point, + reported_addr(stack), (uintptr_t)local_gdt); __builtin_unreachable(); } diff --git a/common/protos/stivale2_rt.asm32u b/common/protos/limine_rt.asm32u similarity index 84% rename from common/protos/stivale2_rt.asm32u rename to common/protos/limine_rt.asm32u index 43222cfe..afc2a9e0 100644 --- a/common/protos/stivale2_rt.asm32u +++ b/common/protos/limine_rt.asm32u @@ -13,12 +13,12 @@ user_ss: resq 1 section .text extern term_write -extern stivale2_rt_stack -extern stivale2_term_callback_ptr -extern stivale2_term_write_ptr +extern limine_rt_stack +extern limine_term_callback_ptr +extern limine_term_write_ptr -global stivale2_term_callback -stivale2_term_callback: +global limine_term_callback +limine_term_callback: bits 32 push ebp mov ebp, esp @@ -53,7 +53,7 @@ bits 64 mov rbx, rsp mov rsp, [rax + user_stack wrt ..gotoff] - call [rax + stivale2_term_callback_ptr wrt ..gotoff] + call [rax + limine_term_callback_ptr wrt ..gotoff] mov rsp, rbx ; Go 32 @@ -77,8 +77,8 @@ bits 32 ret bits 64 -global stivale2_term_write_entry -stivale2_term_write_entry: +global limine_term_write_entry +limine_term_write_entry: push rbx push rbp push r12 @@ -92,7 +92,7 @@ stivale2_term_write_entry: add ebx, _GLOBAL_OFFSET_TABLE_ + $$ - .get_got wrt ..gotpc mov [rbx + user_stack wrt ..gotoff], rsp - mov esp, [rbx + stivale2_rt_stack wrt ..gotoff] + mov esp, [rbx + limine_rt_stack wrt ..gotoff] mov word [rbx + user_cs wrt ..gotoff], cs mov word [rbx + user_ds wrt ..gotoff], ds @@ -115,7 +115,7 @@ bits 32 mov es, ax mov ss, ax - call [ebx + stivale2_term_write_ptr wrt ..gotoff] + call [ebx + limine_term_write_ptr wrt ..gotoff] add esp, 24 push dword [ebx + user_cs wrt ..gotoff] diff --git a/common/protos/stivale2_rt.asmb b/common/protos/limine_rt.asmb similarity index 81% rename from common/protos/stivale2_rt.asmb rename to common/protos/limine_rt.asmb index e979e6ef..2e1cde1f 100644 --- a/common/protos/stivale2_rt.asmb +++ b/common/protos/limine_rt.asmb @@ -11,12 +11,12 @@ user_ss: resq 1 section .text extern term_write -extern stivale2_rt_stack -extern stivale2_term_callback_ptr -extern stivale2_term_write_ptr +extern limine_rt_stack +extern limine_term_callback_ptr +extern limine_term_write_ptr -global stivale2_term_callback -stivale2_term_callback: +global limine_term_callback +limine_term_callback: bits 32 push ebp mov ebp, esp @@ -44,7 +44,7 @@ bits 64 mov rbx, rsp mov rsp, [user_stack] - call [stivale2_term_callback_ptr] + call [limine_term_callback_ptr] mov rsp, rbx ; Go 32 @@ -65,8 +65,8 @@ bits 32 ret -global stivale2_term_write_entry -stivale2_term_write_entry: +global limine_term_write_entry +limine_term_write_entry: bits 64 push rbx push rbp @@ -76,7 +76,7 @@ bits 64 push r15 mov [user_stack], rsp - mov esp, [stivale2_rt_stack] + mov esp, [limine_rt_stack] mov word [user_cs], cs mov word [user_ds], ds @@ -97,7 +97,7 @@ bits 32 mov es, ax mov ss, ax - call [stivale2_term_write_ptr] + call [limine_term_write_ptr] add esp, 24 push dword [user_cs] diff --git a/common/protos/stivale.32.c b/common/protos/stivale.32.c deleted file mode 100644 index 63fc4072..00000000 --- a/common/protos/stivale.32.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include -#include - -noreturn void stivale_spinup_32( - int bits, bool level5pg, bool enable_nx, bool wp, uint32_t pagemap_top_lv, - uint32_t entry_point_lo, uint32_t entry_point_hi, - uint32_t stivale_struct_lo, uint32_t stivale_struct_hi, - uint32_t stack_lo, uint32_t stack_hi, - uint32_t local_gdt) { - 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), - (uint64_t)local_gdt - }; - - if (bits == 64) { - if (enable_nx) { - asm volatile ( - "movl $0xc0000080, %%ecx\n\t" - "rdmsr\n\t" - "btsl $11, %%eax\n\t" - "wrmsr\n\t" - ::: "eax", "ecx", "edx", "memory" - ); - } - - if (level5pg) { - // Enable CR4.LA57 - asm volatile ( - "movl %%cr4, %%eax\n\t" - "btsl $12, %%eax\n\t" - "movl %%eax, %%cr4\n\t" - ::: "eax", "memory" - ); - } - - if (wp) { - asm volatile ( - "movl %%cr0, %%eax\n\t" - "btsl $16, %%eax\n\t" - "movl %%eax, %%cr0\n\t" - ::: "eax", "memory" - ); - } - - 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), %%rdi\n\t" - "movq 0x08(%%rsi), %%rbx\n\t" - "movq 0x18(%%rsi), %%rax\n\t" - "movq 0x10(%%rsi), %%rsi\n\t" - - // Load 64 bit GDT - "lgdt (%%rax)\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 %%esi, %%esi\n\t" - "xorl %%ebp, %%ebp\n\t" - "xorl %%r8d, %%r8d\n\t" - "xorl %%r9d, %%r9d\n\t" - "xorl %%r10d, %%r10d\n\t" - "xorl %%r11d, %%r11d\n\t" - "xorl %%r12d, %%r12d\n\t" - "xorl %%r13d, %%r13d\n\t" - "xorl %%r14d, %%r14d\n\t" - "xorl %%r15d, %%r15d\n\t" - - "iretq\n\t" - ".code32\n\t" - : - : "a" (pagemap_top_lv), "S" (casted_to_64) - : "memory" - ); - } else if (bits == 32) { - asm volatile ( - "cld\n\t" - - "movl %%esi, %%esp\n\t" - "pushl %%edi\n\t" - "pushl $0\n\t" - - "pushfl\n\t" - "pushl $0x18\n\t" - "pushl %%ebx\n\t" - - "xorl %%eax, %%eax\n\t" - "xorl %%ebx, %%ebx\n\t" - "xorl %%ecx, %%ecx\n\t" - "xorl %%edx, %%edx\n\t" - "xorl %%esi, %%esi\n\t" - "xorl %%edi, %%edi\n\t" - "xorl %%ebp, %%ebp\n\t" - - "iretl\n\t" - : - : "D" ((uint32_t)casted_to_64[0]), - "b" ((uint32_t)casted_to_64[1]), - "S" ((uint32_t)casted_to_64[2]) - : "memory" - ); - } - - __builtin_unreachable(); -} diff --git a/common/protos/stivale.c b/common/protos/stivale.c deleted file mode 100644 index 8ac7bf05..00000000 --- a/common/protos/stivale.c +++ /dev/null @@ -1,521 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REPORTED_ADDR(PTR) \ - ((PTR) + ((stivale_hdr.flags & (1 << 3)) ? \ - direct_map_offset : 0)) - -bool stivale_load_by_anchor(void **_anchor, const char *magic, - uint8_t *file, uint64_t filesize) { - struct stivale_anchor *anchor = NULL; - size_t magiclen = strlen(magic); - for (size_t i = 0; i < filesize; i += 16) { - if (memcmp(file + i, magic, magiclen) == 0) { - anchor = (void *)(file + i); - } - } - if (anchor == NULL) { - return false; - } - - memmap_alloc_range(anchor->phys_load_addr, filesize, MEMMAP_KERNEL_AND_MODULES, - true, true, false, false); - memcpy((void *)(uintptr_t)anchor->phys_load_addr, file, filesize); - - size_t bss_size = anchor->phys_bss_end - anchor->phys_bss_start; - memmap_alloc_range(anchor->phys_bss_start, bss_size, MEMMAP_KERNEL_AND_MODULES, - true, true, false, false); - memset((void *)(uintptr_t)anchor->phys_bss_start, 0, bss_size); - - *_anchor = anchor; - - return true; -} - -bool stivale_load(char *config, char *cmdline) { - struct stivale_struct *stivale_struct = ext_mem_alloc(sizeof(struct stivale_struct)); - - // BIOS or UEFI? -#if bios == 1 - stivale_struct->flags |= (1 << 0); -#endif - - stivale_struct->flags |= (1 << 1); // we give colour information - stivale_struct->flags |= (1 << 2); // we give SMBIOS information - - struct file_handle *kernel_file; - - char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); - if (kernel_path == NULL) - panic(true, "stivale: KERNEL_PATH not specified"); - - if ((kernel_file = uri_open(kernel_path)) == NULL) - panic(true, "stivale: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); - - char *kaslr_s = config_get_value(config, 0, "KASLR"); - bool kaslr = true; - if (kaslr_s != NULL && strcmp(kaslr_s, "no") == 0) - kaslr = false; - - struct stivale_header stivale_hdr; - - bool level5pg = false; - uint64_t slide = 0; - uint64_t entry_point = 0; - - uint8_t *kernel = freadall(kernel_file, STIVALE_MMAP_BOOTLOADER_RECLAIMABLE); - int bits = elf_bits(kernel); - bool loaded_by_anchor = false; - - size_t kernel_file_size = kernel_file->size; - - fclose(kernel_file); - - if (bits == -1) { - struct stivale_anchor *anchor; - if (!stivale_load_by_anchor((void **)&anchor, "STIVALE1 ANCHOR", kernel, kernel_file_size)) { - goto fail; - } - - bits = anchor->bits; - - memcpy(&stivale_hdr, (void *)(uintptr_t)anchor->phys_stivalehdr, - sizeof(struct stivale_header)); - - loaded_by_anchor = true; - } else { - switch (bits) { - case 64: - if (elf64_load_section(kernel, &stivale_hdr, ".stivalehdr", - sizeof(struct stivale_header), slide)) { - goto fail; - } - break; - case 32: - if (elf32_load_section(kernel, &stivale_hdr, ".stivalehdr", - sizeof(struct stivale_header))) { - goto fail; - } - break; - } - } - - print("stivale: Loading kernel `%s`...\n", kernel_path); - - int ret = 0; - switch (bits) { - case 64: { - // Check if 64 bit CPU - uint32_t eax, ebx, ecx, edx; - if (!cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx) || !(edx & (1 << 29))) { - panic(true, "stivale: This CPU does not support 64-bit mode."); - } - // Check if 5-level paging is available - if (cpuid(0x00000007, 0, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 16))) { - printv("stivale: CPU has 5-level paging support\n"); - level5pg = true; - } - - if (!loaded_by_anchor) { - if (elf64_load(kernel, &entry_point, NULL, &slide, - STIVALE_MMAP_KERNEL_AND_MODULES, kaslr, false, - NULL, NULL, false, NULL, NULL, NULL, NULL)) - panic(true, "stivale: ELF64 load failure"); - - ret = elf64_load_section(kernel, &stivale_hdr, ".stivalehdr", - sizeof(struct stivale_header), slide); - } - - break; - } - case 32: { - if (!loaded_by_anchor) { - if (elf32_load(kernel, (uint32_t *)&entry_point, NULL, STIVALE_MMAP_KERNEL_AND_MODULES)) - panic(true, "stivale: ELF32 load failure"); - - ret = elf32_load_section(kernel, &stivale_hdr, ".stivalehdr", - sizeof(struct stivale_header)); - } - - break; - } - default: - panic(true, "stivale: Not 32 nor 64-bit kernel. What is this?"); - } - - printv("stivale: %u-bit kernel detected\n", bits); - - switch (ret) { - case 1: - panic(true, "stivale: File is not a valid ELF."); - case 2: - panic(true, "stivale: Section .stivalehdr not found."); - case 3: - panic(true, "stivale: Section .stivalehdr exceeds the size of the struct."); - case 4: - panic(true, "stivale: Section .stivalehdr is smaller than size of the struct."); - } - - if ((stivale_hdr.flags & (1 << 3)) && bits == 32) { - panic(true, "stivale: Higher half addresses header flag not supported in 32-bit mode."); - } - - bool want_5lv = level5pg && (stivale_hdr.flags & (1 << 1)); - - uint64_t direct_map_offset = want_5lv ? 0xff00000000000000 : 0xffff800000000000; - - struct gdtr *local_gdt = ext_mem_alloc(sizeof(struct gdtr)); - local_gdt->limit = gdt.limit; - uint64_t local_gdt_base = (uint64_t)gdt.ptr; - if (stivale_hdr.flags & (1 << 3)) { - local_gdt_base += direct_map_offset; - } - local_gdt->ptr = local_gdt_base; -#if defined (__i386__) - local_gdt->ptr_hi = local_gdt_base >> 32; -#endif - - if (stivale_hdr.entry_point != 0) - entry_point = stivale_hdr.entry_point; - - if (verbose) { - print("stivale: Kernel slide: %X\n", slide); - - print("stivale: Entry point at: %X\n", entry_point); - print("stivale: Requested stack at: %X\n", stivale_hdr.stack); - } - - // The spec says the stack has to be 16-byte aligned - if ((stivale_hdr.stack & (16 - 1)) != 0) { - print("stivale: WARNING: Requested stack is not 16-byte aligned\n"); - } - - // It also says the stack cannot be NULL for 32-bit kernels - if (bits == 32 && stivale_hdr.stack == 0) { - panic(true, "stivale: The stack cannot be 0 for 32-bit kernels"); - } - - stivale_struct->module_count = 0; - uint64_t *prev_mod_ptr = &stivale_struct->modules; - for (int i = 0; ; i++) { - struct conf_tuple conf_tuple = - config_get_tuple(config, i, "MODULE_PATH", "MODULE_STRING"); - - char *module_path = conf_tuple.value1; - char *module_string = conf_tuple.value2; - - if (module_path == NULL) - break; - - stivale_struct->module_count++; - - struct stivale_module *m = ext_mem_alloc(sizeof(struct stivale_module)); - - // TODO: perhaps change the module string to to be a pointer. - // - // NOTE: By default, the module string is the file name. - if (module_string == NULL) { - size_t str_len = strlen(module_path); - - if (str_len > 127) - str_len = 127; - - memcpy(m->string, module_path, str_len); - } else { - // TODO perhaps change this to be a pointer - size_t str_len = strlen(module_string); - - if (str_len > 127) - str_len = 127; - - memcpy(m->string, module_string, str_len); - } - - print("stivale: Loading module `%s`...\n", module_path); - - struct file_handle *f; - if ((f = uri_open(module_path)) == NULL) - panic(true, "stivale: Failed to open module with path `%s`. Is the path correct?", module_path); - - 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 = REPORTED_ADDR((uint64_t)(size_t)m); - prev_mod_ptr = &m->next; - - fclose(f); - - if (verbose) { - print("stivale: Requested module %u:\n", i); - print(" Path: %s\n", module_path); - print(" String: %s\n", m->string); - print(" Begin: %X\n", m->begin); - print(" End: %X\n", m->end); - } - } - - uint64_t rsdp = (uint64_t)(size_t)acpi_get_rsdp(); - - if (rsdp) - stivale_struct->rsdp = REPORTED_ADDR(rsdp); - - 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(); - printv("stivale: Current epoch: %U\n", stivale_struct->epoch); - - term_deinit(); - - if (stivale_hdr.flags & (1 << 0)) { - size_t req_width = stivale_hdr.framebuffer_width; - size_t req_height = stivale_hdr.framebuffer_height; - size_t req_bpp = stivale_hdr.framebuffer_bpp; - - char *resolution = config_get_value(config, 0, "RESOLUTION"); - if (resolution != NULL) - parse_resolution(&req_width, &req_height, &req_bpp, resolution); - - struct fb_info fbinfo; -#if uefi == 1 - gop_force_16 = true; -#endif - if (!fb_init(&fbinfo, req_width, req_height, req_bpp)) - panic(true, "stivale: Unable to set video mode"); - - memmap_alloc_range(fbinfo.framebuffer_addr, - (uint64_t)fbinfo.framebuffer_pitch * fbinfo.framebuffer_height, - MEMMAP_FRAMEBUFFER, false, false, false, true); - - 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; - stivale_struct->framebuffer_pitch = fbinfo.framebuffer_pitch; - stivale_struct->fb_memory_model = STIVALE_FBUF_MMODEL_RGB; - stivale_struct->fb_red_mask_size = fbinfo.red_mask_size; - stivale_struct->fb_red_mask_shift = fbinfo.red_mask_shift; - stivale_struct->fb_green_mask_size = fbinfo.green_mask_size; - stivale_struct->fb_green_mask_shift = fbinfo.green_mask_shift; - stivale_struct->fb_blue_mask_size = fbinfo.blue_mask_size; - stivale_struct->fb_blue_mask_shift = fbinfo.blue_mask_shift; - } else { -#if uefi == 1 - panic(true, "stivale: Cannot use text mode with UEFI."); -#elif bios == 1 - size_t rows, cols; - init_vga_textmode(&rows, &cols, false); -#endif - } - -#if uefi == 1 - efi_exit_boot_services(); -#endif - - pagemap_t pagemap = {0}; - if (bits == 64) - 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)) { - if ((stivale_hdr.flags & (1 << 4)) == 0) { - panic(false, "stivale: Could not allocate low memory area"); - } - } - - struct e820_entry_t *mmap_copy = ext_mem_alloc(256 * sizeof(struct e820_entry_t)); - - size_t mmap_entries; - struct e820_entry_t *mmap = get_memmap(&mmap_entries); - - if (mmap_entries > 256) { - panic(false, "stivale: Too many memory map entries!"); - } - - memcpy(mmap_copy, mmap, mmap_entries * sizeof(struct e820_entry_t)); - - stivale_struct->memory_map_entries = (uint64_t)mmap_entries; - stivale_struct->memory_map_addr = REPORTED_ADDR((uint64_t)(size_t)mmap_copy); - - stivale_spinup(bits, want_5lv, &pagemap, - entry_point, REPORTED_ADDR((uint64_t)(uintptr_t)stivale_struct), - stivale_hdr.stack, false, false, (uintptr_t)local_gdt); - - __builtin_unreachable(); - -fail: - pmm_free(kernel, kernel_file_size); - pmm_free(stivale_struct, sizeof(struct stivale_struct)); - 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, - uint64_t direct_map_offset) { - pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4); - - if (ranges_count == 0) { - // Map 0 to 2GiB at 0xffffffff80000000 - for (uint64_t i = 0; i < 0x80000000; i += 0x40000000) { - map_page(pagemap, 0xffffffff80000000 + i, i, 0x03, Size1GiB); - } - } else { - for (size_t i = 0; i < ranges_count; i++) { - uint64_t virt = ranges[i].base; - uint64_t phys; - - if (virt & ((uint64_t)1 << 63)) { - if (want_fully_virtual) { - phys = physical_base + (virt - virtual_base); - } else { - phys = virt - FIXED_HIGHER_HALF_OFFSET_64; - } - } else { - panic(false, "stivale2: Protected memory ranges are only supported for higher half kernels"); - } - - uint64_t pf = VMM_FLAG_PRESENT | - (ranges[i].permissions & ELF_PF_X ? 0 : VMM_FLAG_NOEXEC) | - (ranges[i].permissions & ELF_PF_W ? VMM_FLAG_WRITE : 0); - - for (uint64_t j = 0; j < ranges[i].length; j += 0x1000) { - map_page(pagemap, virt + j, phys + j, pf, Size4KiB); - } - } - } - - // Sub 2MiB mappings - for (uint64_t i = 0; i < 0x200000; i += 0x1000) { - if (!(i == 0 && unmap_null)) - map_page(pagemap, i, i, 0x03, Size4KiB); - map_page(pagemap, direct_map_offset + i, i, 0x03, Size4KiB); - } - - // Map 2MiB to 4GiB at higher half base and 0 - // - // NOTE: We cannot just directly map from 2MiB to 4GiB with 1GiB - // pages because if you do the math. - // - // start = 0x200000 - // end = 0x40000000 - // - // pages_required = (end - start) / (4096 * 512 * 512) - // - // So we map 2MiB to 1GiB with 2MiB pages and then map the rest - // with 1GiB pages :^) - for (uint64_t i = 0x200000; i < 0x40000000; i += 0x200000) { - map_page(pagemap, i, i, 0x03, Size2MiB); - map_page(pagemap, direct_map_offset + i, i, 0x03, Size2MiB); - } - - for (uint64_t i = 0x40000000; i < 0x100000000; i += 0x40000000) { - map_page(pagemap, i, i, 0x03, Size1GiB); - map_page(pagemap, direct_map_offset + i, i, 0x03, Size1GiB); - } - - size_t _memmap_entries = memmap_entries; - struct e820_entry_t *_memmap = - ext_mem_alloc(_memmap_entries * sizeof(struct e820_entry_t)); - for (size_t i = 0; i < _memmap_entries; i++) - _memmap[i] = memmap[i]; - - // Map any other region of memory from the memmap - for (size_t i = 0; i < _memmap_entries; i++) { - uint64_t base = _memmap[i].base; - uint64_t length = _memmap[i].length; - uint64_t top = base + length; - - if (base < 0x100000000) - base = 0x100000000; - - if (base >= top) - continue; - - uint64_t aligned_base = ALIGN_DOWN(base, 0x40000000); - uint64_t aligned_top = ALIGN_UP(top, 0x40000000); - uint64_t aligned_length = aligned_top - aligned_base; - - for (uint64_t j = 0; j < aligned_length; j += 0x40000000) { - uint64_t page = aligned_base + j; - map_page(pagemap, page, page, 0x03, Size1GiB); - map_page(pagemap, direct_map_offset + page, page, 0x03, Size1GiB); - } - } - - return pagemap; -} - -#if uefi == 1 -extern symbol ImageBase; -#endif - -noreturn void stivale_spinup_32( - int bits, bool level5pg, uint32_t pagemap_top_lv, - uint32_t entry_point_lo, uint32_t entry_point_hi, - uint32_t stivale_struct_lo, uint32_t stivale_struct_hi, - uint32_t stack_lo, uint32_t stack_hi, uint32_t local_gdt); - -noreturn void stivale_spinup( - int bits, bool level5pg, pagemap_t *pagemap, - uint64_t entry_point, uint64_t _stivale_struct, uint64_t stack, - bool enable_nx, bool wp, uint32_t local_gdt) { -#if bios == 1 - if (bits == 64) { - // If we're going 64, we might as well call this BIOS interrupt - // to tell the BIOS that we are entering Long Mode, since it is in - // the specification. - struct rm_regs r = {0}; - r.eax = 0xec00; - r.ebx = 0x02; // Long mode only - rm_int(0x15, &r, &r); - } -#endif - - if (enable_nx) { - vmm_assert_nx(); - } - - pic_mask_all(); - io_apic_mask_all(); - - irq_flush_type = IRQ_PIC_APIC_FLUSH; - - common_spinup(stivale_spinup_32, 12, - bits, level5pg, enable_nx, wp, (uint32_t)(uintptr_t)pagemap->top_level, - (uint32_t)entry_point, (uint32_t)(entry_point >> 32), - (uint32_t)_stivale_struct, (uint32_t)(_stivale_struct >> 32), - (uint32_t)stack, (uint32_t)(stack >> 32), local_gdt); -} diff --git a/common/protos/stivale.h b/common/protos/stivale.h deleted file mode 100644 index 83c99d53..00000000 --- a/common/protos/stivale.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __PROTOS__STIVALE_H__ -#define __PROTOS__STIVALE_H__ - -#include -#include -#include -#include -#include - -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, - uint64_t direct_map_offset); -noreturn void stivale_spinup( - int bits, bool level5pg, pagemap_t *pagemap, - uint64_t entry_point, uint64_t stivale_struct, uint64_t stack, - bool enable_nx, bool wp, uint32_t local_gdt); - -#endif diff --git a/common/protos/stivale2.c b/common/protos/stivale2.c deleted file mode 100644 index 0024ff97..00000000 --- a/common/protos/stivale2.c +++ /dev/null @@ -1,856 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define REPORTED_ADDR(PTR) \ - ((PTR) + ((stivale2_hdr.flags & (1 << 1)) ? \ - direct_map_offset : 0)) - -#define get_phys_addr(addr) ({ \ - uintptr_t r1; \ - if ((addr) & ((uint64_t)1 << 63)) { \ - if (want_fully_virtual) { \ - r1 = physical_base + ((addr) - virtual_base); \ - } else { \ - r1 = (addr) - FIXED_HIGHER_HALF_OFFSET_64; \ - } \ - } else { \ - r1 = addr; \ - } \ - r1; \ -}) - -#define get_tag(s, id) ({ \ - void *r; \ - struct stivale2_tag *tag = (void *)get_phys_addr((s)->tags); \ - for (;;) { \ - if (tag == NULL) { \ - r = NULL; \ - break; \ - } \ - if (tag->identifier == (id)) { \ - r = tag; \ - break; \ - } \ - tag = (void *)get_phys_addr(tag->next); \ - } \ - r; \ -}) - -#define append_tag(S, TAG) ({ \ - (TAG)->next = (S)->tags; \ - (S)->tags = REPORTED_ADDR((uint64_t)(uintptr_t)TAG); \ -}) - -#if defined (__i386__) -extern symbol stivale2_term_write_entry; -void *stivale2_rt_stack = NULL; -uint64_t stivale2_term_callback_ptr = 0; -uint64_t stivale2_term_write_ptr = 0; -void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); -#endif - -bool stivale2_load(char *config, char *cmdline) { - struct stivale2_struct *stivale2_struct = ext_mem_alloc(sizeof(struct stivale2_struct)); - - struct file_handle *kernel_file; - - char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); - if (kernel_path == NULL) - panic(true, "stivale2: KERNEL_PATH not specified"); - - if ((kernel_file = uri_open(kernel_path)) == NULL) - panic(true, "stivale2: Failed to open kernel with path `%s`. Is the path correct?", kernel_path); - - char *kaslr_s = config_get_value(config, 0, "KASLR"); - bool kaslr = true; - if (kaslr_s != NULL && strcmp(kaslr_s, "no") == 0) - kaslr = false; - - struct stivale2_header stivale2_hdr; - - bool level5pg = false; - uint64_t slide = 0; - uint64_t entry_point = 0; - - struct elf_range *ranges; - uint64_t ranges_count; - - uint8_t *kernel = freadall(kernel_file, STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE); - int bits = elf_bits(kernel); - bool loaded_by_anchor = false; - - size_t kernel_file_size = kernel_file->size; - - struct volume *kernel_volume = kernel_file->vol; - - fclose(kernel_file); - - if (bits == -1) { - struct stivale2_anchor *anchor; - if (!stivale_load_by_anchor((void **)&anchor, "STIVALE2 ANCHOR", kernel, kernel_file_size)) { - goto fail; - } - - bits = anchor->bits; - - memcpy(&stivale2_hdr, (void *)(uintptr_t)anchor->phys_stivale2hdr, - sizeof(struct stivale2_header)); - - loaded_by_anchor = true; - } else { - switch (bits) { - case 64: - if (elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr", - sizeof(struct stivale2_header), slide)) { - goto fail; - } - break; - case 32: - if (elf32_load_section(kernel, &stivale2_hdr, ".stivale2hdr", - sizeof(struct stivale2_header))) { - goto fail; - } - break; - } - } - - print("stivale2: Loading kernel `%s`...\n", kernel_path); - - bool want_pmrs = false; - bool want_fully_virtual = false; - - uint64_t physical_base, virtual_base; - - int ret = 0; - switch (bits) { - case 64: { - // Check if 64 bit CPU - uint32_t eax, ebx, ecx, edx; - if (!cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx) || !(edx & (1 << 29))) { - panic(true, "stivale2: This CPU does not support 64-bit mode."); - } - // Check if 5-level paging is available - if (cpuid(0x00000007, 0, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 16))) { - printv("stivale2: CPU has 5-level paging support\n"); - level5pg = true; - } - - if (loaded_by_anchor && (stivale2_hdr.flags & (1 << 2))) { - panic(true, "stivale2: PMRs are not supported for anchored kernels"); - } - - if (!loaded_by_anchor) { - ret = elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr", - sizeof(struct stivale2_header), 0); - if (ret) { - goto failed_to_load_header_section; - } - - if ((stivale2_hdr.flags & (1 << 2))) { - if (bits == 32) { - panic(true, "stivale2: PMRs are not supported for 32-bit kernels"); - } - want_pmrs = true; - } - - if (want_pmrs && (stivale2_hdr.flags & (1 << 3))) { - want_fully_virtual = true; - } - - if (elf64_load(kernel, &entry_point, NULL, &slide, - STIVALE2_MMAP_KERNEL_AND_MODULES, kaslr, false, - want_pmrs ? &ranges : NULL, - want_pmrs ? &ranges_count : NULL, - want_fully_virtual, &physical_base, &virtual_base, - NULL, NULL)) - panic(true, "stivale2: ELF64 load failure"); - - if (want_fully_virtual) { - printv("stivale2: Physical base: %X\n", physical_base); - printv("stivale2: Virtual base: %X\n", virtual_base); - } - - ret = elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr", - sizeof(struct stivale2_header), slide); - } - - break; - } - case 32: { - if (!loaded_by_anchor) { - if (elf32_load(kernel, (uint32_t *)&entry_point, NULL, STIVALE2_MMAP_KERNEL_AND_MODULES)) - panic(true, "stivale2: ELF32 load failure"); - - ret = elf32_load_section(kernel, &stivale2_hdr, ".stivale2hdr", - sizeof(struct stivale2_header)); - } - - break; - } - default: - panic(true, "stivale2: Not 32 nor 64-bit kernel. What is this?"); - } - - printv("stivale2: %u-bit kernel detected\n", bits); - -failed_to_load_header_section: - switch (ret) { - case 1: - panic(true, "stivale2: File is not a valid ELF."); - case 2: - panic(true, "stivale2: Section .stivale2hdr not found."); - case 3: - panic(true, "stivale2: Section .stivale2hdr exceeds the size of the struct."); - case 4: - panic(true, "stivale2: Section .stivale2hdr is smaller than size of the struct."); - } - - if ((stivale2_hdr.flags & (1 << 1)) && bits == 32) { - panic(true, "stivale2: Higher half addresses header flag not supported in 32-bit mode."); - } - - 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(true, "stivale2: Requested HHDM slide alignment is not a multiple of 2MiB"); - } - - // XXX: Assert that slt->alignment is not larger than 1GiB and ignore the value altogether. - // This is required for 1GiB pages. - if (((uint64_t)0x40000000 % slt->alignment) != 0) { - panic(true, "stivale2: 1 GiB is not a multiple of HHDM slide alignment"); - } - - direct_map_offset += (rand64() & ~((uint64_t)0x40000000 - 1)) & 0xfffffffffff; - } - } - - struct gdtr *local_gdt = ext_mem_alloc(sizeof(struct gdtr)); - local_gdt->limit = gdt.limit; - uint64_t local_gdt_base = (uint64_t)gdt.ptr; - if (stivale2_hdr.flags & (1 << 1)) { - local_gdt_base += direct_map_offset; - } - local_gdt->ptr = local_gdt_base; -#if defined (__i386__) - local_gdt->ptr_hi = local_gdt_base >> 32; -#endif - - if (stivale2_hdr.entry_point != 0) - entry_point = stivale2_hdr.entry_point; - - if (verbose) { - print("stivale2: Kernel slide: %X\n", slide); - - print("stivale2: Entry point at: %X\n", entry_point); - print("stivale2: Requested stack at: %X\n", stivale2_hdr.stack); - } - - // The spec says the stack has to be 16-byte aligned - if ((stivale2_hdr.stack & (16 - 1)) != 0) { - print("stivale2: WARNING: Requested stack is not 16-byte aligned\n"); - } - - // It also says the stack cannot be NULL for 32-bit kernels - if (bits == 32 && stivale2_hdr.stack == 0) { - panic(true, "stivale2: The stack cannot be 0 for 32-bit kernels"); - } - - strcpy(stivale2_struct->bootloader_brand, "Limine"); - strcpy(stivale2_struct->bootloader_version, LIMINE_VERSION); - - ////////////////////////////////////////////// - // Create boot volume tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_boot_volume *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_boot_volume)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_BOOT_VOLUME_ID; - - if (kernel_volume->guid_valid) { - tag->flags |= (1 << 0); - memcpy(&tag->guid, &kernel_volume->guid, sizeof(struct stivale2_guid)); - } - - if (kernel_volume->part_guid_valid) { - tag->flags |= (1 << 1); - memcpy(&tag->part_guid, &kernel_volume->part_guid, sizeof(struct stivale2_guid)); - } - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create kernel file struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_kernel_file *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_kernel_file)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_KERNEL_FILE_ID; - - tag->kernel_file = REPORTED_ADDR((uint64_t)(uintptr_t)kernel); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create kernel file v2 struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_kernel_file_v2 *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_kernel_file_v2)); - - tag->tag.identifier = STIVALE2_STRUCT_TAG_KERNEL_FILE_V2_ID; - tag->kernel_file = REPORTED_ADDR((uint64_t)(uintptr_t)kernel); - tag->kernel_size = kernel_file_size; - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create kernel slide struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_kernel_slide *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_kernel_slide)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID; - - tag->kernel_slide = slide; - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create firmware struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_firmware *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_firmware)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_FIRMWARE_ID; - -#if bios == 1 - tag->flags = 1 << 0; // bit 0 = BIOS boot -#endif - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create modules struct tag - ////////////////////////////////////////////// - { - size_t module_count; - for (module_count = 0; ; module_count++) { - char *module_file = config_get_value(config, module_count, "MODULE_PATH"); - if (module_file == NULL) - break; - } - - struct stivale2_struct_tag_modules *tag = - ext_mem_alloc(sizeof(struct stivale2_struct_tag_modules) - + sizeof(struct stivale2_module) * module_count); - - tag->tag.identifier = STIVALE2_STRUCT_TAG_MODULES_ID; - tag->module_count = module_count; - - for (size_t i = 0; i < module_count; i++) { - struct conf_tuple conf_tuple = - config_get_tuple(config, i, "MODULE_PATH", "MODULE_STRING"); - - char *module_path = conf_tuple.value1; - char *module_string = conf_tuple.value2; - - struct stivale2_module *m = &tag->modules[i]; - - // TODO: perhaps change the module string to to be a pointer. - // - // NOTE: By default, the module string is the file name. - if (module_string == NULL) { - size_t str_len = strlen(module_path); - - if (str_len > 127) - str_len = 127; - - memcpy(m->string, module_path, str_len); - } else { - size_t str_len = strlen(module_string); - - if (str_len > 127) - str_len = 127; - - memcpy(m->string, module_string, str_len); - } - - print("stivale2: Loading module `%s`...\n", module_path); - - struct file_handle *f; - if ((f = uri_open(module_path)) == NULL) - panic(true, "stivale2: Failed to open module with path `%s`. Is the path correct?", module_path); - - m->begin = REPORTED_ADDR((uint64_t)(size_t)freadall(f, STIVALE2_MMAP_KERNEL_AND_MODULES)); - m->end = m->begin + f->size; - - fclose(f); - - if (verbose) { - print("stivale2: Requested module %u:\n", i); - print(" Path: %s\n", module_path); - print(" String: %s\n", m->string); - print(" Begin: %X\n", m->begin); - print(" End: %X\n", m->end); - } - } - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create RSDP struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_rsdp *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_rsdp)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_RSDP_ID; - - uint64_t rsdp = (uint64_t)(size_t)acpi_get_rsdp(); - if (rsdp) - tag->rsdp = REPORTED_ADDR(rsdp); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create SMBIOS struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_smbios *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_smbios)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_SMBIOS_ID; - - 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) - tag->smbios_entry_32 = REPORTED_ADDR(smbios_entry_32); - if (smbios_entry_64) - tag->smbios_entry_64 = REPORTED_ADDR(smbios_entry_64); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create cmdline struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_cmdline *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_cmdline)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_CMDLINE_ID; - - tag->cmdline = REPORTED_ADDR((uint64_t)(size_t)cmdline); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create epoch struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_epoch *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_epoch)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_EPOCH_ID; - - tag->epoch = time(); - printv("stivale2: Current epoch: %U\n", tag->epoch); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // Create framebuffer struct tag - ////////////////////////////////////////////// - { - - struct fb_info *fb = NULL; - struct fb_info _fb; - - struct stivale2_header_tag_framebuffer *hdrtag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_FRAMEBUFFER_ID); - - size_t req_width = 0, req_height = 0, req_bpp = 0; - - if (hdrtag != NULL) { - req_width = hdrtag->framebuffer_width; - req_height = hdrtag->framebuffer_height; - req_bpp = hdrtag->framebuffer_bpp; - } - - char *resolution = config_get_value(config, 0, "RESOLUTION"); - if (resolution != NULL) - parse_resolution(&req_width, &req_height, &req_bpp, resolution); - - struct stivale2_header_tag_any_video *avtag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_ANY_VIDEO_ID); - -#if uefi == 1 - if (hdrtag == NULL && avtag == NULL) { - panic(true, "stivale2: Cannot use text mode with UEFI."); - } -#endif - - char *textmode_str = config_get_value(config, 0, "TEXTMODE"); - bool textmode = textmode_str != NULL && strcmp(textmode_str, "yes") == 0; - - int preference = 0; - if (avtag != NULL) { - preference = textmode ? 1 : avtag->preference; - } - - struct stivale2_header_tag_terminal *terminal_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_TERMINAL_ID); - - if (bits == 64 && terminal_hdr_tag != NULL) { - quiet = false; - serial = false; - - if (bios && - ((avtag == NULL && hdrtag == NULL) || (avtag != NULL && preference == 1))) { - term_textmode(); - textmode = true; - } else { -#if uefi == 1 - gop_force_16 = true; -#endif - term_vbe(req_width, req_height); - - if (current_video_mode < 0) { - panic(true, "stivale2: Failed to initialise terminal"); - } - - fb = &fbinfo; - - textmode = false; - } - - struct stivale2_struct_tag_terminal *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_terminal)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_TERMINAL_ID; - - if (terminal_hdr_tag->flags & (1 << 0)) { - // We provide callback - tag->flags |= (1 << 2); - if (terminal_hdr_tag->callback != 0) { -#if defined (__i386__) - term_callback = stivale2_term_callback; - stivale2_term_callback_ptr = terminal_hdr_tag->callback; -#elif defined (__x86_64__) - term_callback = (void *)terminal_hdr_tag->callback; -#endif - } - } - - // We provide max allowed string length - tag->flags |= (1 << 1); - tag->max_length = 0; - - // We provide context control - tag->flags |= (1 << 3); - -#if defined (__i386__) - if (stivale2_rt_stack == NULL) { - stivale2_rt_stack = ext_mem_alloc(8192) + 8192; - } - - stivale2_term_write_ptr = (uintptr_t)term_write; - tag->term_write = (uintptr_t)(void *)stivale2_term_write_entry; -#elif defined (__x86_64__) - tag->term_write = (uintptr_t)term_write; -#endif - - // We provide rows and cols - tag->flags |= (1 << 0); - tag->cols = term_cols; - tag->rows = term_rows; - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - - if (textmode) { -#if bios == 1 - goto have_tm_tag; -#endif - } else { - goto have_fb_tag; - } - } else { - fb = &_fb; - } - - term_deinit(); - - if (hdrtag != NULL || (avtag != NULL && uefi) || (avtag != NULL && preference == 0)) { - term_deinit(); - -#if uefi == 1 - gop_force_16 = true; -#endif - if (fb_init(fb, req_width, req_height, req_bpp)) { -have_fb_tag:; - struct stivale2_struct_tag_framebuffer *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_framebuffer)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID; - - memmap_alloc_range(fb->framebuffer_addr, - (uint64_t)fb->framebuffer_pitch * fb->framebuffer_height, - MEMMAP_FRAMEBUFFER, false, false, false, true); - - tag->memory_model = STIVALE2_FBUF_MMODEL_RGB; - tag->framebuffer_addr = REPORTED_ADDR(fb->framebuffer_addr); - tag->framebuffer_width = fb->framebuffer_width; - tag->framebuffer_height = fb->framebuffer_height; - tag->framebuffer_bpp = fb->framebuffer_bpp; - tag->framebuffer_pitch = fb->framebuffer_pitch; - tag->red_mask_size = fb->red_mask_size; - tag->red_mask_shift = fb->red_mask_shift; - tag->green_mask_size = fb->green_mask_size; - tag->green_mask_shift = fb->green_mask_shift; - tag->blue_mask_size = fb->blue_mask_size; - tag->blue_mask_shift = fb->blue_mask_shift; - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - } else { -#if bios == 1 - size_t rows, cols; - init_vga_textmode(&rows, &cols, false); - -have_tm_tag:; - struct stivale2_struct_tag_textmode *tmtag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_textmode)); - tmtag->tag.identifier = STIVALE2_STRUCT_TAG_TEXTMODE_ID; - - tmtag->address = 0xb8000; - tmtag->rows = 25; - tmtag->cols = 80; - tmtag->bytes_per_char = 2; - - append_tag(stivale2_struct, (struct stivale2_tag *)tmtag); -#endif - } - } - - ////////////////////////////////////////////// - // Create EDID struct tag - ////////////////////////////////////////////// - { - struct edid_info_struct *edid_info = get_edid_info(); - - if (edid_info != NULL) { - struct stivale2_struct_tag_edid *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_edid) + sizeof(struct edid_info_struct)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_EDID_ID; - - tag->edid_size = sizeof(struct edid_info_struct); - - memcpy(tag->edid_information, edid_info, sizeof(struct edid_info_struct)); - - append_tag(stivale2_struct, (struct stivale2_tag *)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 - ////////////////////////////////////////////// - if (boot_volume->pxe) { - struct stivale2_struct_tag_pxe_server_info *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_pxe_server_info)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_PXE_SERVER_INFO; - tag->server_ip = get_boot_server_info(); - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } -#endif - - ////////////////////////////////////////////// - // Create PMRs struct tag - ////////////////////////////////////////////// - { - if (want_pmrs) { - struct stivale2_struct_tag_pmrs *tag = - ext_mem_alloc(sizeof(struct stivale2_struct_tag_pmrs) - + ranges_count * sizeof(struct stivale2_pmr)); - - tag->tag.identifier = STIVALE2_STRUCT_TAG_PMRS_ID; - - tag->entries = ranges_count; - - memcpy(tag->pmrs, ranges, ranges_count * sizeof(struct stivale2_pmr)); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - } - - ////////////////////////////////////////////// - // Create PMRs struct tag - ////////////////////////////////////////////// - { - if (want_fully_virtual) { - struct stivale2_struct_tag_kernel_base_address *tag = - ext_mem_alloc(sizeof(struct stivale2_struct_tag_kernel_base_address)); - - tag->tag.identifier = STIVALE2_STRUCT_TAG_KERNEL_BASE_ADDRESS_ID; - - tag->physical_base_address = physical_base; - tag->virtual_base_address = virtual_base; - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - } - - ////////////////////////////////////////////// - // Create EFI system table struct tag - ////////////////////////////////////////////// -#if uefi == 1 - { - struct stivale2_struct_tag_efi_system_table *tag = ext_mem_alloc(sizeof(struct stivale2_struct_tag_efi_system_table)); - tag->tag.identifier = STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID; - - tag->system_table = REPORTED_ADDR((uint64_t)(uintptr_t)gST); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } -#endif - - bool unmap_null = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_UNMAP_NULL_ID) ? true : false; - - pagemap_t pagemap = {0}; - if (bits == 64) - pagemap = stivale_build_pagemap(want_5lv, unmap_null, - want_pmrs ? ranges : NULL, - want_pmrs ? ranges_count : 0, - want_fully_virtual, physical_base, virtual_base, - direct_map_offset); - -#if uefi == 1 - efi_exit_boot_services(); -#endif - - ////////////////////////////////////////////// - // Create SMP struct tag - ////////////////////////////////////////////// - { - struct stivale2_header_tag_smp *smp_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_SMP_ID); - if (smp_hdr_tag != NULL) { - struct stivale2_struct_tag_smp *tag; - struct smp_information *smp_info; - size_t cpu_count; - uint32_t bsp_lapic_id; - smp_info = init_smp(sizeof(struct stivale2_struct_tag_smp), (void **)&tag, - &cpu_count, &bsp_lapic_id, - bits == 64, want_5lv, - pagemap, smp_hdr_tag->flags & 1, want_pmrs, - stivale2_hdr.flags & (1 << 1) ? direct_map_offset : 0, - want_pmrs); - - if (smp_info != NULL) { - tag->tag.identifier = STIVALE2_STRUCT_TAG_SMP_ID; - tag->bsp_lapic_id = bsp_lapic_id; - tag->cpu_count = cpu_count; - tag->flags |= (smp_hdr_tag->flags & 1) && x2apic_check(); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - } - } - - ////////////////////////////////////////////// - // Create memmap struct tag - ////////////////////////////////////////////// - { - struct stivale2_struct_tag_memmap *tag = - ext_mem_alloc(sizeof(struct stivale2_struct_tag_memmap) + - sizeof(struct e820_entry_t) * 256); - - // Reserve 32K at 0x70000, if possible - if (!memmap_alloc_range(0x70000, 0x8000, MEMMAP_USABLE, true, false, false, false)) { - if ((stivale2_hdr.flags & (1 << 4)) == 0) { - panic(false, "stivale2: Could not allocate low memory area"); - } - } - - size_t mmap_entries; - struct e820_entry_t *mmap = get_memmap(&mmap_entries); - - if (mmap_entries > 256) { - panic(false, "stivale2: Too many memory map entries!"); - } - - tag->tag.identifier = STIVALE2_STRUCT_TAG_MEMMAP_ID; - tag->entries = (uint64_t)mmap_entries; - - memcpy((void*)tag + sizeof(struct stivale2_struct_tag_memmap), - mmap, sizeof(struct e820_entry_t) * mmap_entries); - - append_tag(stivale2_struct, (struct stivale2_tag *)tag); - } - - ////////////////////////////////////////////// - // List tags - ////////////////////////////////////////////// - if (verbose) { - print("stivale2: Generated tags:\n"); - struct stivale2_tag *taglist = - (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 - ((stivale2_hdr.flags & (1 << 1)) ? direct_map_offset : 0)); - } else { - break; - } - } - } - - // Clear terminal for kernels that will use the stivale2 terminal - term_write((uint64_t)(uintptr_t)("\e[2J\e[H"), 7); - - term_runtime = true; - - stivale_spinup(bits, want_5lv, &pagemap, entry_point, - REPORTED_ADDR((uint64_t)(uintptr_t)stivale2_struct), - stivale2_hdr.stack, want_pmrs, want_pmrs, (uintptr_t)local_gdt); - - __builtin_unreachable(); - -fail: - pmm_free(kernel, kernel_file_size); - pmm_free(stivale2_struct, sizeof(struct stivale2_struct)); - return false; -} diff --git a/common/protos/stivale2.h b/common/protos/stivale2.h deleted file mode 100644 index 9674fcff..00000000 --- a/common/protos/stivale2.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __PROTOS__STIVALE2_H__ -#define __PROTOS__STIVALE2_H__ - -#include - -bool stivale2_load(char *config, char *cmdline); - -#endif diff --git a/test/GNUmakefile b/test/GNUmakefile index d4910af4..3415fae5 100644 --- a/test/GNUmakefile +++ b/test/GNUmakefile @@ -29,7 +29,6 @@ INTERNAL_LD_FLAGS_MULTIBOOT1 := \ --no-dynamic-linker \ INTERNALCFLAGS := \ - -I../stivale \ -I. \ -I.. \ -std=c11 \ @@ -46,7 +45,7 @@ INTERNALCFLAGS := \ all: test.elf multiboot2.elf multiboot.elf -test.elf: stivale.o stivale2.o limine.o e9print.o memory.o +test.elf: limine.o e9print.o memory.o $(LD) $^ $(LDFLAGS) $(INTERNALLDFLAGS) -o $@ multiboot2.elf: multiboot2_trampoline.o @@ -66,6 +65,6 @@ multiboot.elf: multiboot_trampoline.o nasm -felf32 $< -o $@ clean: - rm -rf test.elf limine.o stivale.o stivale2.o e9print.o memory.o + rm -rf test.elf limine.o e9print.o memory.o rm -rf multiboot2.o multiboot2.elf multiboot2_trampoline.o rm -rf multiboot.o multiboot_trampoline.o multiboot.elf diff --git a/test/e9print.c b/test/e9print.c index fc0ecd13..bab06a5e 100644 --- a/test/e9print.c +++ b/test/e9print.c @@ -1,13 +1,13 @@ #include #include -void (*stivale2_print)(const char *buf, size_t size) = NULL; +void (*limine_print)(const char *buf, size_t size) = NULL; static const char CONVERSION_TABLE[] = "0123456789abcdef"; void e9_putc(char c) { - if (stivale2_print != NULL) - stivale2_print(&c, 1); + if (limine_print != NULL) + limine_print(&c, 1); __asm__ __volatile__ ("outb %0, %1" :: "a" (c), "Nd" (0xe9) : "memory"); } diff --git a/test/e9print.h b/test/e9print.h index 052dbac4..88bbb5d8 100644 --- a/test/e9print.h +++ b/test/e9print.h @@ -3,7 +3,7 @@ #include #include -extern void (*stivale2_print)(const char *buf, size_t size); +extern void (*limine_print)(const char *buf, size_t size); void e9_putc(char c); void e9_print(const char *msg); diff --git a/test/limine-fwcfg.cfg b/test/limine-fwcfg.cfg index 4711e1db..9f52f61a 100644 --- a/test/limine-fwcfg.cfg +++ b/test/limine-fwcfg.cfg @@ -11,10 +11,7 @@ BACKDROP_COLOUR=008080 :fwcfg:// test -COMMENT=Test of the stivale2 boot protocol. - # Let's use autodetection -#PROTOCOL=stivale2 RESOLUTION=800x600 KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel KERNEL_CMDLINE=Woah! Another example! @@ -24,5 +21,5 @@ MODULE_STRING=yooooo # Test that the module string provided to the kernel will be # the module path since a module string is not specified. -# (cc CONFIG.md stivale2.`MODULE_STRING` section) +# (cc CONFIG.md limine.`MODULE_STRING` section) MODULE_PATH=fwcfg:///opt/org.limine-bootloader.background diff --git a/test/limine.c b/test/limine.c index a559ca51..6015a0fb 100644 --- a/test/limine.c +++ b/test/limine.c @@ -201,9 +201,9 @@ static void write_shim(const char *s, uint64_t l) { _terminal_request.response->write(terminal, s, l); } -static void limine_main(void) { +void limine_main(void) { if (_terminal_request.response) { - stivale2_print = write_shim; + limine_print = write_shim; } e9_printf("\nWe're alive"); diff --git a/test/limine.cfg b/test/limine.cfg index 1fe115b4..3132242e 100644 --- a/test/limine.cfg +++ b/test/limine.cfg @@ -47,32 +47,6 @@ TERM_BACKDROP=008080 :+Legacy COMMENT=Directory containing legacy entries. - ::Stivale Test - COMMENT=Stivale1 test. - - PROTOCOL=stivale - KERNEL_PATH=boot:///boot/test.elf - KERNEL_CMDLINE=This is an example kernel command line. - - MODULE_PATH=boot:///boot/test.elf - MODULE_STRING=This is the first module. - - MODULE_PATH=boot:///boot/bg.bmp - MODULE_STRING=This is the second module. - - ::Stivale2 Test - COMMENT=Stivale2 test. - - PROTOCOL=stivale2 - KERNEL_PATH=boot:///boot/test.elf - KERNEL_CMDLINE=This is an example kernel command line. - - MODULE_PATH=boot:///boot/test.elf - MODULE_STRING=This is the first module. - - MODULE_PATH=boot:///boot/bg.bmp - MODULE_STRING=This is the second module. - ::Multiboot1 Test COMMENT=Test of the multiboot1 boot protocol. diff --git a/test/linker.ld b/test/linker.ld index 627a2187..c8a9b308 100644 --- a/test/linker.ld +++ b/test/linker.ld @@ -1,8 +1,7 @@ -ENTRY(stivale_main) +ENTRY(limine_main) PHDRS { - null PT_NULL FLAGS(0) ; /* Null segment */ text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ @@ -25,14 +24,6 @@ SECTIONS QUAD(0) } :rodata - .stivalehdr : { - KEEP(*(.stivalehdr)) - } :rodata - - .stivale2hdr : { - KEEP(*(.stivale2hdr)) - } :rodata - .rodata : { *(.rodata*) } :rodata diff --git a/test/stivale.c b/test/stivale.c deleted file mode 100644 index 8106e357..00000000 --- a/test/stivale.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -static uint8_t stack[4096] = {0}; -void stivale_main(struct stivale_struct *info); - -__attribute__((section(".stivalehdr"), used)) -struct stivale_header header = { - .stack = (uint64_t)(uintptr_t)stack + sizeof(stack), - .framebuffer_bpp = 0, - .framebuffer_width = 0, - .framebuffer_height = 0, - .flags = (1 << 3) | (1 << 4), - .entry_point = (uint64_t)(uintptr_t)stivale_main -}; - -void stivale_main(struct stivale_struct *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); - - struct stivale_mmap_entry *memmap = ((struct stivale_mmap_entry *)(info->memory_map_addr)); - for (size_t i = 0; i < info->memory_map_entries; i++) { - struct stivale_mmap_entry e = memmap[i]; - e9_printf("\tEntry %d: [%x+%x] %x", i, e.base, e.length, e.type); - } - - e9_printf("Framebuffer at %x with specifics:", info->framebuffer_addr); - e9_printf("\tPitch: %d", info->framebuffer_pitch); - e9_printf("\tWidth: %d", info->framebuffer_width); - e9_printf("\tHeight: %d", info->framebuffer_height); - e9_printf("\tBPP: %d", info->framebuffer_bpp); - if (info->flags & (1 << 1)) { - e9_printf("\tExtended colour information provided:"); - e9_printf("\t\tMemory model: %d", info->fb_memory_model); - e9_printf("\t\tRed mask size: %d", info->fb_red_mask_size); - e9_printf("\t\tRed mask shift: %d", info->fb_red_mask_shift); - e9_printf("\t\tGreen mask size: %d", info->fb_green_mask_size); - e9_printf("\t\tGreen mask shift: %d", info->fb_green_mask_shift); - e9_printf("\t\tBlue mask size: %d", info->fb_blue_mask_size); - e9_printf("\t\tBlue mask shift: %d", info->fb_blue_mask_shift); - } - if (info->flags & (1 << 2)) { - e9_printf("\tSMBIOS information provided:"); - e9_printf("\t\t32-bit entry: %x", info->smbios_entry_32); - e9_printf("\t\t64-bit entry: %x", info->smbios_entry_64); - } - - e9_printf("RSDP at %x", info->rsdp); - - e9_printf("Module map at %x with modules:", info->modules); - 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); - modules = (struct stivale_module *)e.next; - } - - e9_printf("Epoch is %x", info->epoch); - e9_printf("Flags are %x", info->flags); - - // Guru meditation. - for (;;); -} diff --git a/test/stivale2.c b/test/stivale2.c deleted file mode 100644 index cb5e59ee..00000000 --- a/test/stivale2.c +++ /dev/null @@ -1,281 +0,0 @@ -#include -#include -#include -#include - -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 = (uint64_t)&slide_hhdm - }, - .flags = 0 -}; - -struct stivale2_header_tag_smp smp_request = { - .tag = { - .identifier = STIVALE2_HEADER_TAG_SMP_ID, - .next = (uint64_t)&terminal_request - }, - .flags = 0 -}; - -struct stivale2_tag unmap_null_request = { - .identifier = STIVALE2_HEADER_TAG_UNMAP_NULL_ID, - .next = (uint64_t)&smp_request -}; - -struct stivale2_header_tag_any_video any_video_request = { - .tag = { - .identifier = STIVALE2_HEADER_TAG_ANY_VIDEO_ID, - .next = (uint64_t)&unmap_null_request - }, - .preference = 0 -}; - -__attribute__((section(".stivale2hdr"), used)) -struct stivale2_header header2 = { - .entry_point = (uint64_t)stivale2_main, - .stack = (uintptr_t)stacks[0] + sizeof(stack), - .flags = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4), - .tags = (uint64_t)&any_video_request -}; - -static volatile int cpu_up = 0; - -static void ap_entry(struct stivale2_smp_info *s) { - e9_printf(" AP %d started", s->lapic_id); - cpu_up = 1; - for (;;) __asm__("hlt"); -} - -static void print_guid(struct stivale2_guid guid) { - e9_printf("\t\ta: %x", guid.a); - e9_printf("\t\tb: %x", guid.b); - e9_printf("\t\tc: %x", guid.c); - e9_puts("\t\td: ["); - - for (uint8_t i = 0; i < 8; i++) { - e9_printf("\t\t\t%x,", guid.d[i]); - } - - e9_puts("\t\t]\n"); -} - -void stivale2_main(struct stivale2_struct *info) { - // Print the tags. - struct stivale2_tag *tag = (struct stivale2_tag *)info->tags; - - while (tag != NULL) { - if (tag->identifier == STIVALE2_STRUCT_TAG_TERMINAL_ID) { - struct stivale2_struct_tag_terminal *t = (void *)tag; - stivale2_print = (void *)(uintptr_t)t->term_write; - } - tag = (void *)tag->next; - } - - // Print stuff. - e9_puts("Stivale2 info passed to the kernel:"); - e9_printf("Bootloader brand: %s", info->bootloader_brand); - e9_printf("Bootloader version: %s", info->bootloader_version); - - // Print the tags. - tag = (struct stivale2_tag *)info->tags; - - while (tag != NULL) { - switch (tag->identifier) { - case STIVALE2_STRUCT_TAG_CMDLINE_ID: { - struct stivale2_struct_tag_cmdline *c = (struct stivale2_struct_tag_cmdline *)tag; - e9_puts("Commandline tag:"); - e9_printf("\tCmdline: %s", (char*)(c->cmdline)); - break; - } - case STIVALE2_STRUCT_TAG_MEMMAP_ID: { - struct stivale2_struct_tag_memmap *m = (struct stivale2_struct_tag_memmap *)tag; - e9_puts("Memmap tag:"); - e9_printf("\tEntries: %d", m->entries); - size_t total_mem = 0; - for (size_t i = 0; i < m->entries; i++) { - struct stivale2_mmap_entry me = m->memmap[i]; - e9_printf("\t\t[%x+%x] %x", me.base, me.length, me.type); - if (m->memmap[i].type == 1) { - total_mem += m->memmap[i].length; - } - } - e9_printf("\tTotal usable memory: %d", total_mem); - break; - } - case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: { - struct stivale2_struct_tag_framebuffer *f = (struct stivale2_struct_tag_framebuffer *)tag; - e9_puts("Framebuffer tag:"); - e9_printf("\tAddress: %x", f->framebuffer_addr); - e9_printf("\tWidth: %d", f->framebuffer_width); - e9_printf("\tHeight: %d", f->framebuffer_height); - e9_printf("\tPitch: %d", f->framebuffer_pitch); - e9_printf("\tBPP: %d", f->framebuffer_bpp); - e9_printf("\tMemory model: %d", f->memory_model); - e9_printf("\tRed mask size: %d", f->red_mask_size); - e9_printf("\tRed mask size: %d", f->red_mask_shift); - e9_printf("\tGreen mask size: %d", f->green_mask_size); - e9_printf("\tGreen mask size: %d", f->green_mask_shift); - e9_printf("\tBlue mask size: %d", f->blue_mask_size); - e9_printf("\tBlue mask size: %d", f->blue_mask_shift); - break; - } - case STIVALE2_STRUCT_TAG_TEXTMODE_ID: { - struct stivale2_struct_tag_textmode *tm = (struct stivale2_struct_tag_textmode *)tag; - e9_puts("Textmode tag"); - break; - } - case STIVALE2_STRUCT_TAG_EDID_ID: { - struct stivale2_struct_tag_edid *edid = (struct stivale2_struct_tag_edid *)tag; - - e9_printf("EDID information at %x:", edid->edid_information); - e9_printf("\tSize: %d", edid->edid_size); - break; - } - case STIVALE2_STRUCT_TAG_FB_MTRR_ID: { - e9_puts("Framebuffer WC MTRR tag:"); - e9_puts("\tFramebuffer WC MTRR enabled"); - break; - } - case STIVALE2_STRUCT_TAG_TERMINAL_ID: { - struct stivale2_struct_tag_terminal *term = (struct stivale2_struct_tag_terminal *)tag; - - e9_puts("Terminal tag:"); - e9_printf("\tTerminal write entry point at: %x", term->term_write); - break; - } - case STIVALE2_STRUCT_TAG_MODULES_ID: { - struct stivale2_struct_tag_modules *m = (struct stivale2_struct_tag_modules *)tag; - e9_puts("Modules tag:"); - e9_printf("\tCount: %d", m->module_count); - for (size_t i = 0; i < m->module_count; i++) { - struct stivale2_module me = m->modules[i]; - e9_printf("\t\t[%x+%x] %s", me.begin, me.end, me.string); - } - break; - } - case STIVALE2_STRUCT_TAG_RSDP_ID: { - struct stivale2_struct_tag_rsdp *r = (struct stivale2_struct_tag_rsdp *)tag; - e9_puts("RSDP tag:"); - e9_printf("\tRSDP: %x", r->rsdp); - break; - } - case STIVALE2_STRUCT_TAG_SMBIOS_ID: { - struct stivale2_struct_tag_smbios *r = (struct stivale2_struct_tag_smbios *)tag; - e9_puts("SMBIOS tag:"); - e9_printf("\tFlags: %x", r->flags); - e9_printf("\tSMBIOS 32-bit entry point: %x", r->smbios_entry_32); - e9_printf("\tSMBIOS 64-bit entry point: %x", r->smbios_entry_64); - break; - } - case STIVALE2_STRUCT_TAG_EPOCH_ID: { - struct stivale2_struct_tag_epoch *e = (struct stivale2_struct_tag_epoch *)tag; - e9_puts("Epoch tag:"); - e9_printf("\tEpoch: %x", e->epoch); - break; - } - case STIVALE2_STRUCT_TAG_FIRMWARE_ID: { - struct stivale2_struct_tag_firmware *f = (struct stivale2_struct_tag_firmware *)tag; - e9_puts("Firmware tag:"); - e9_printf("\tFlags: %x", f->flags); - break; - } - case STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID: { - struct stivale2_struct_tag_efi_system_table *t = (struct stivale2_struct_tag_efi_system_table *)tag; - e9_printf("EFI system table at: %x", t->system_table); - break; - } - case STIVALE2_STRUCT_TAG_KERNEL_FILE_ID: { - struct stivale2_struct_tag_kernel_file *t = (struct stivale2_struct_tag_kernel_file *)tag; - e9_printf("Raw kernel file loaded at: %x", t->kernel_file); - break; - } - case STIVALE2_STRUCT_TAG_KERNEL_FILE_V2_ID: { - struct stivale2_struct_tag_kernel_file_v2 *t = (struct stivale2_struct_tag_kernel_file_v2 *)tag; - e9_puts("Kernel file V2 tag:"); - e9_printf("\tkernel_file: %x", t->kernel_file); - e9_printf("\tkernel_size: %x", t->kernel_size); - break; - } - case STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID: { - struct stivale2_struct_tag_kernel_slide *t = (struct stivale2_struct_tag_kernel_slide *)tag; - e9_printf("Kernel slide: %x", t->kernel_slide); - break; - } - case STIVALE2_STRUCT_TAG_PMRS_ID: { - struct stivale2_struct_tag_pmrs *t = (struct stivale2_struct_tag_pmrs *)tag; - e9_puts("PMRs tag:"); - e9_printf("\t%d ranges:", t->entries); - for (size_t i = 0; i < t->entries; i++) { - e9_printf("\t\tBase: %x Length: %x Perms: %x", - t->pmrs[i].base, t->pmrs[i].length, t->pmrs[i].permissions); - } - 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:"); - e9_printf("\tPhysical base address: %x", t->physical_base_address); - e9_printf("\tVirtual base address: %x", t->virtual_base_address); - break; - } - case STIVALE2_STRUCT_TAG_BOOT_VOLUME_ID: { - struct stivale2_struct_tag_boot_volume *t = (void *)tag; - e9_puts("Boot volume:"); - e9_printf("\tGUID:"); - print_guid(t->guid); - e9_printf("\tPartition GUID:"); - print_guid(t->part_guid); - break; - } - case STIVALE2_STRUCT_TAG_SMP_ID: { - struct stivale2_struct_tag_smp *s = (struct stivale2_struct_tag_smp *)tag; - e9_puts("SMP tag:"); - e9_printf("\tFlags: %x", s->flags); - e9_printf("\tBSP LAPIC ID: %d", s->bsp_lapic_id); - e9_printf("\tCPU Count: %d", s->cpu_count); - for (size_t i = 0; i < s->cpu_count; i++) { - struct stivale2_smp_info *in = &s->smp_info[i]; - e9_printf("\t\tProcessor ID: %d", in->processor_id); - e9_printf("\t\tLAPIC ID: %d", in->lapic_id); - e9_printf("\t\tTarget Stack: %x", in->target_stack); - e9_printf("\t\tGOTO Address: %x", in->goto_address); - e9_printf("\t\tExtra Argument: %x", in->extra_argument); - if (in->lapic_id != s->bsp_lapic_id) { - in->target_stack = (uintptr_t)stacks[in->lapic_id] + sizeof(stack); - in->goto_address = (uintptr_t)ap_entry; - while (cpu_up == 0); - cpu_up = 0; - } - } - break; - } - default: - e9_printf("BUG: Unidentified tag %x", tag->identifier); - } - - tag = (struct stivale2_tag *)tag->next; - } - - // Enter our sublime pale slumber. - for (;;) __asm__("hlt"); -}