:: commit 8e54ea461baa52e61ff0b9891100e825e5a60a85

mintsuki <mintsuki@protonmail.com> — 2022-07-05 16:53

parents: 1dd81d4534

protos: Remove ugly .32.c files and replace them with pure asm files

diff --git a/common/GNUmakefile b/common/GNUmakefile
index 7444764a..893f3d90 100644
--- a/common/GNUmakefile
+++ b/common/GNUmakefile
@@ -395,14 +395,6 @@ endif
 
 -include $(HEADER_DEPS)
 
-ifeq ($(TARGET), uefi-x86-64)
-$(call MKESCAPE,$(BUILDDIR))/%.32.o: %.32.c $(call MKESCAPE,$(BUILDDIR))/limine-efi
-	mkdir -p "$$(dirname '$(call SHESCAPE,$@)')"
-	$(CROSS_CC) $(CROSS_CFLAGS) $(INTERNAL_CFLAGS32) -c '$(call SHESCAPE,$<)' -o '$(call SHESCAPE,$@).32'
-	$(CROSS_OBJCOPY) -I elf32-i386 -O elf64-x86-64 '$(call SHESCAPE,$@).32' '$(call SHESCAPE,$@)'
-	rm '$(call SHESCAPE,$@).32'
-endif
-
 ifeq ($(TARGET), bios)
 $(call MKESCAPE,$(BUILDDIR))/%.o: %.asm_ia32
 	mkdir -p "$$(dirname '$(call SHESCAPE,$@)')"
diff --git a/common/protos/limine.32.c b/common/protos/limine.32.c
deleted file mode 100644
index a4614580..00000000
--- a/common/protos/limine.32.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <stdnoreturn.h>
-#include <mm/vmm.h>
-
-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_32.asm_x86 b/common/protos/limine_32.asm_x86
new file mode 100644
index 00000000..94ac426f
--- /dev/null
+++ b/common/protos/limine_32.asm_x86
@@ -0,0 +1,97 @@
+bits 32
+
+section .text
+
+global limine_spinup_32
+limine_spinup_32:
+    ; Enable EFER.NXE
+    mov ecx, 0xc0000080
+    rdmsr
+    bts eax, 11
+    wrmsr
+
+    ; Enable CR4.LA57
+    cmp dword [esp+4], 0 ; level5pg
+    je .no_la57
+    mov eax, cr4
+    bts eax, 12
+    mov cr4, eax
+  .no_la57:
+
+    ; Enable CR0.WP
+    mov eax, cr0
+    bts eax, 16
+    mov cr0, eax
+
+    cld
+
+    mov eax, [esp+8] ; pagemap_top_lv
+    mov cr3, eax
+
+    ; Enable CR4.PAE
+    mov eax, cr4
+    bts eax, 5
+    mov cr4, eax
+
+    ; Enable EFER.LME
+    mov eax, 0xc0000080
+    rdmsr
+    bts eax, 8
+    wrmsr
+
+    ; Enable CR0.PG
+    mov eax, cr0
+    bts eax, 31
+    mov cr0, eax
+
+    ; Go 64
+    push 0x28
+    call .p1
+  .p1:
+    add dword [esp], .mode64 - .p1
+    retfd
+
+bits 64
+  .mode64:
+    mov eax, 0x30
+    mov ds, eax
+    mov es, eax
+    mov fs, eax
+    mov gs, eax
+    mov ss, eax
+
+    ; Load 64-bit GDT
+    mov eax, [rsp+28] ; local_gdt
+    lgdt [rax]
+
+    ; Push fake return address
+    mov rsi, [rsp+20] ; stack
+    sub rsi, 8
+    mov qword [rsi], 0
+
+    ; Prepare iretq frame
+    mov rax, qword [rsp+12] ; entry_point
+    push 0x30
+    push rsi
+    pushfq
+    push 0x28
+    push rax
+
+    ; Zero out all GPRs
+    xor eax, eax
+    xor ebx, ebx
+    xor ecx, ecx
+    xor edx, edx
+    xor esi, esi
+    xor edi, edi
+    xor ebp, ebp
+    xor r8d, r8d
+    xor r9d, r9d
+    xor r10d, r10d
+    xor r11d, r11d
+    xor r12d, r12d
+    xor r13d, r13d
+    xor r14d, r14d
+    xor r15d, r15d
+
+    iretq
diff --git a/common/protos/linux.32.c b/common/protos/linux.32.c
deleted file mode 100644
index ac40ce1e..00000000
--- a/common/protos/linux.32.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdint.h>
-#include <stdnoreturn.h>
-#include <sys/gdt.h>
-
-noreturn void linux_spinup(void *entry, void *boot_params) {
-    struct gdt_desc linux_gdt_descs[4];
-    linux_gdt_descs[0] = (struct gdt_desc){0};
-    linux_gdt_descs[1] = (struct gdt_desc){0};
-
-    linux_gdt_descs[2] = (struct gdt_desc){
-        .limit       = 0xffff,
-        .base_low    = 0x0000,
-        .base_mid    = 0x00,
-        .access      = 0b10011010,
-        .granularity = 0b11001111,
-        .base_hi     = 0x00
-    };
-
-    linux_gdt_descs[3] = (struct gdt_desc){
-        .limit       = 0xffff,
-        .base_low    = 0x0000,
-        .base_mid    = 0x00,
-        .access      = 0b10010010,
-        .granularity = 0b11001111,
-        .base_hi     = 0x00
-    };
-
-    struct gdtr linux_gdt;
-    linux_gdt.limit = sizeof(linux_gdt_descs) - 1;
-    linux_gdt.ptr   = (uintptr_t)linux_gdt_descs;
-
-    asm volatile (
-        "lgdt %0\n\t"
-
-        "pushl $0x10\n\t"
-        "call 1f\n\t"
-        "1:\n\t"
-        "addl $2f-1b, (%%esp)\n\t"
-        "lret\n\t"
-        "2:\n\t"
-
-        "movl $0x18, %%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"
-
-        "xorl %%ebp, %%ebp\n\t"
-        "xorl %%edi, %%edi\n\t"
-        "xorl %%ebx, %%ebx\n\t"
-
-        "cld\n\t"
-
-        "jmp *%%ecx\n\t"
-        :
-        : "m"(linux_gdt), "c"(entry), "S"(boot_params)
-        : "memory"
-    );
-
-    __builtin_unreachable();
-}
diff --git a/common/protos/linux_32.asm_x86 b/common/protos/linux_32.asm_x86
new file mode 100644
index 00000000..a575f6bd
--- /dev/null
+++ b/common/protos/linux_32.asm_x86
@@ -0,0 +1,67 @@
+section .data
+
+align 16
+linux_gdt:
+    dq 0
+
+    dq 0
+
+    dw 0xffff
+    dw 0x0000
+    db 0x00
+    db 10011010b
+    db 11001111b
+    db 0x00
+
+    dw 0xffff
+    dw 0x0000
+    db 0x00
+    db 10010010b
+    db 11001111b
+    db 0x00
+
+  .end:
+
+align 16
+linux_gdt_ptr:
+    dw (linux_gdt.end - linux_gdt) - 1
+    dd 0
+
+bits 32
+
+section .text
+
+global linux_spinup
+linux_spinup:
+    call .p0
+  .p0:
+    pop eax
+    lea ebx, [eax - (linux_spinup.p0 - linux_gdt_ptr)]
+    lea ecx, [eax - (linux_spinup.p0 - linux_gdt)]
+    mov [ebx+2], ecx
+
+    lgdt [ebx]
+
+    push 0x10
+    call .p1
+  .p1:
+    add dword [esp], .fj - .p1
+    retfd
+
+  .fj:
+    mov eax, 0x18
+    mov ds, eax
+    mov es, eax
+    mov fs, eax
+    mov gs, eax
+    mov ss, eax
+
+    xor ebp, ebp
+    xor edi, edi
+    xor ebx, ebx
+
+    mov esi, [esp+8] ; boot_params
+
+    cld
+
+    jmp [esp+4]
diff --git a/common/protos/multiboot.32.c b/common/protos/multiboot.32.c
deleted file mode 100644
index c5f8b9f1..00000000
--- a/common/protos/multiboot.32.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdint.h>
-#include <stdnoreturn.h>
-#if bios == 1
-#  include <sys/idt.h>
-#endif
-
-noreturn void multiboot_spinup_32(
-                  uint32_t reloc_stub,
-                  uint32_t magic, uint32_t protocol_info,
-                  uint32_t entry_point,
-                  uint32_t elf_ranges, uint32_t elf_ranges_count) {
-#if bios == 1
-    struct idtr idtr;
-
-    idtr.limit = 0x3ff;
-    idtr.ptr = 0;
-
-    asm volatile (
-        "lidt %0"
-        :
-        : "m" (idtr)
-        : "memory"
-    );
-#endif
-
-    asm volatile (
-        "jmp *%%ebx"
-        :
-        : "b"(reloc_stub), "S"(magic),
-          "a"(elf_ranges), "d"(elf_ranges_count),
-          "D"(protocol_info), "c"(entry_point)
-        : "memory"
-    );
-
-    __builtin_unreachable();
-}
diff --git a/common/protos/multiboot_32.asm_x86 b/common/protos/multiboot_32.asm_x86
new file mode 100644
index 00000000..3bf746b3
--- /dev/null
+++ b/common/protos/multiboot_32.asm_x86
@@ -0,0 +1,21 @@
+bits 32
+
+section .text
+global multiboot_spinup_32:
+multiboot_spinup_32:
+    sub esp, 6
+    mov word [esp-2], 0x3ff
+    mov dword [esp], 0
+    lidt [esp-2]
+    add esp, 6
+
+    add esp, 4 ; return address
+
+    pop ebx ; reloc_stub
+    pop esi ; magic
+    pop edi ; protocol_info
+    pop ecx ; entry_point
+    pop eax ; elf_ranges
+    pop edx ; elf_ranges_count
+
+    jmp ebx
tab: 248 wrap: offon