summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-07-16 13:33:00 +0200
committerdzwdz2022-07-16 13:33:00 +0200
commit912d2e3c7eb1baa71dda2c0a28aa5809eaa96f27 (patch)
tree4e27f3538466d5fd63a311d50916039a7a15a485 /src
parent1eeb66af44ab335888410d716d604e569f20866e (diff)
amd64: barely boot into kernel code
Diffstat (limited to 'src')
-rw-r--r--src/kernel/arch/amd64/32/32 (renamed from src/kernel/arch/i386/gdt/gdt.c)2
-rw-r--r--src/kernel/arch/amd64/32/boot.s86
-rw-r--r--src/kernel/arch/amd64/32/farjump.s (renamed from src/kernel/arch/i386/gdt/farjump.s)0
-rw-r--r--src/kernel/arch/amd64/32/gdt.c118
-rw-r--r--src/kernel/arch/amd64/32/gdt.h (renamed from src/kernel/arch/i386/gdt.h)1
-rw-r--r--src/kernel/arch/amd64/32/paging.c131
-rw-r--r--src/kernel/arch/amd64/ata.c (renamed from src/kernel/arch/i386/ata.c)4
-rw-r--r--src/kernel/arch/amd64/ata.h (renamed from src/kernel/arch/i386/ata.h)0
-rw-r--r--src/kernel/arch/amd64/boot.c (renamed from src/kernel/arch/i386/boot.c)26
-rw-r--r--src/kernel/arch/amd64/boot.h (renamed from src/kernel/arch/i386/boot.h)2
-rw-r--r--src/kernel/arch/amd64/boot64.s13
-rw-r--r--src/kernel/arch/amd64/debug.c (renamed from src/kernel/arch/i386/debug.c)12
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.c (renamed from src/kernel/arch/i386/driver/fsroot.c)4
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.h (renamed from src/kernel/arch/i386/driver/fsroot.h)0
-rw-r--r--src/kernel/arch/amd64/driver/ps2.c (renamed from src/kernel/arch/i386/driver/ps2.c)4
-rw-r--r--src/kernel/arch/amd64/driver/ps2.h (renamed from src/kernel/arch/i386/driver/ps2.h)0
-rw-r--r--src/kernel/arch/amd64/driver/serial.c (renamed from src/kernel/arch/i386/driver/serial.c)6
-rw-r--r--src/kernel/arch/amd64/driver/serial.h (renamed from src/kernel/arch/i386/driver/serial.h)0
-rw-r--r--src/kernel/arch/amd64/interrupts/idt.c (renamed from src/kernel/arch/i386/interrupts/idt.c)45
-rw-r--r--src/kernel/arch/amd64/interrupts/idt.h (renamed from src/kernel/arch/i386/interrupts/idt.h)0
-rw-r--r--src/kernel/arch/amd64/interrupts/irq.c (renamed from src/kernel/arch/i386/interrupts/irq.c)4
-rw-r--r--src/kernel/arch/amd64/interrupts/irq.h (renamed from src/kernel/arch/i386/interrupts/irq.h)0
-rw-r--r--src/kernel/arch/amd64/interrupts/isr.c (renamed from src/kernel/arch/i386/interrupts/isr.c)22
-rw-r--r--src/kernel/arch/amd64/interrupts/isr.h (renamed from src/kernel/arch/i386/interrupts/isr.h)3
-rw-r--r--src/kernel/arch/amd64/interrupts/isr_stub.s81
-rw-r--r--src/kernel/arch/amd64/multiboot.h (renamed from src/kernel/arch/i386/multiboot.h)17
-rw-r--r--src/kernel/arch/amd64/multiboot.s (renamed from src/kernel/arch/i386/multiboot.s)0
-rw-r--r--src/kernel/arch/amd64/pagedir.c (renamed from src/kernel/arch/i386/pagedir.c)9
-rw-r--r--src/kernel/arch/amd64/port_io.h (renamed from src/kernel/arch/i386/port_io.h)0
-rw-r--r--src/kernel/arch/amd64/registers.h (renamed from src/kernel/arch/i386/registers.h)9
-rw-r--r--src/kernel/arch/amd64/sysenter.c (renamed from src/kernel/arch/i386/sysenter.c)3
-rw-r--r--src/kernel/arch/amd64/sysenter.h (renamed from src/kernel/arch/i386/sysenter.h)0
-rw-r--r--src/kernel/arch/amd64/sysenter.s (renamed from src/kernel/arch/i386/sysenter.s)78
-rw-r--r--src/kernel/arch/amd64/tty/tty.c (renamed from src/kernel/arch/i386/tty/tty.c)4
-rw-r--r--src/kernel/arch/amd64/tty/tty.h (renamed from src/kernel/arch/i386/tty/tty.h)0
-rw-r--r--src/kernel/arch/amd64/tty/vga.c (renamed from src/kernel/arch/i386/tty/vga.c)2
-rw-r--r--src/kernel/arch/generic.h4
-rw-r--r--src/kernel/arch/i386/boot.s34
-rw-r--r--src/kernel/arch/i386/interrupts/isr_stub.s64
-rw-r--r--src/kernel/panic.h2
-rw-r--r--src/kernel/proc.c1
-rw-r--r--src/kernel/vfs/request.c2
-rw-r--r--src/shared/printf.c4
-rw-r--r--src/user/lib/syscall.s31
44 files changed, 589 insertions, 239 deletions
diff --git a/src/kernel/arch/i386/gdt/gdt.c b/src/kernel/arch/amd64/32/32
index 3521052..9bd97e6 100644
--- a/src/kernel/arch/i386/gdt/gdt.c
+++ b/src/kernel/arch/amd64/32/32
@@ -1,5 +1,5 @@
#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/gdt.h>
+#include <kernel/arch/amd64/gdt.h>
#include <shared/mem.h>
#include <stdbool.h>
#include <stdint.h>
diff --git a/src/kernel/arch/amd64/32/boot.s b/src/kernel/arch/amd64/32/boot.s
new file mode 100644
index 0000000..eb33c28
--- /dev/null
+++ b/src/kernel/arch/amd64/32/boot.s
@@ -0,0 +1,86 @@
+.section .text
+.global _start
+.type _start, @function
+_start:
+ mov $_stack_top, %esp
+ push %ebx // save the address of the multiboot struct
+
+ mov $0x80000000, %eax // check CPUID extended functions
+ cpuid
+ cmp $0x80000001, %eax
+ jb panic_early
+
+ mov $0x80000001, %eax
+ cpuid
+ test $(1<<29), %edx // check long mode support
+ jz panic_early
+
+ mov %cr4, %eax
+ or $(1<<5), %eax // PAE
+ mov %eax, %cr4
+
+ call pml4_identity_init
+ mov $pml4_identity, %eax
+ mov %eax, %cr3
+
+ mov $0xC0000080, %ecx // EFER MSR
+ rdmsr
+ or $(1 | 1<<8 | 1<<11), %eax // sysenter | long mode | NX
+ wrmsr
+
+ mov %cr0, %eax
+ or $0x80000000, %eax
+ mov %eax, %cr0
+
+ call gdt_init
+ lgdt (lgdt_arg)
+
+ pop %edi
+
+ // TODO import gdt.h for globals
+ mov $(2<<3), %eax
+ mov %eax, %ds // SEG_r0data
+ mov %eax, %ss
+ mov %eax, %es
+ mov %eax, %fs
+ mov %eax, %gs
+
+ ljmp $(1<<3), $boot64 // SEG_r0code
+
+panic_early:
+ // output a vga Fuck
+ movl $0x4F754F46, 0xB872A
+ movl $0x4F6B4F63, 0xB872E
+ jmp cpu_halt
+
+// TODO not part of anything yet
+ call sysenter_setup
+ // TODO will fail
+ push %ebx // address of the Multiboot struct
+ call kmain_early
+
+.global cpu_shutdown
+.type cpu_shutdown, @function
+cpu_shutdown:
+/* This quits QEMU. While I couldn't find this officially documented anywhere,
+ * it is used by QEMU in tests/tcg/i386/system/boot.S (as of commit 40d6ee), so
+ * I assume that this is safe-ish to use */
+ mov $0x604, %edx
+ mov $0x2000, %eax
+ outw %ax, %dx
+
+.global cpu_halt
+.type cpu_halt, @function
+cpu_halt:
+ cli
+1: hlt
+ jmp 1b
+
+
+.global cpu_pause
+.type cpu_pause, @function
+cpu_pause:
+ sti
+ hlt
+ cli
+ ret
diff --git a/src/kernel/arch/i386/gdt/farjump.s b/src/kernel/arch/amd64/32/farjump.s
index 2885d2b..2885d2b 100644
--- a/src/kernel/arch/i386/gdt/farjump.s
+++ b/src/kernel/arch/amd64/32/farjump.s
diff --git a/src/kernel/arch/amd64/32/gdt.c b/src/kernel/arch/amd64/32/gdt.c
new file mode 100644
index 0000000..2229330
--- /dev/null
+++ b/src/kernel/arch/amd64/32/gdt.c
@@ -0,0 +1,118 @@
+#include <kernel/arch/amd64/32/gdt.h>
+#include <kernel/arch/generic.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+extern char _isr_mini_stack;
+
+struct gdt_entry {
+ uint64_t limit_low : 16;
+ uint64_t base_low : 24;
+ uint64_t accessed : 1; // set by the processor
+ // CODE | DATA
+ uint64_t rw : 1; // readable? | writeable?
+ uint64_t conforming : 1; // conforming? | expands down?
+ uint64_t code : 1; // 1 | 0
+
+ uint64_t codeordata : 1; // 1 for everything other than TSS and LDT
+ uint64_t ring : 2;
+ uint64_t present : 1; // always 1
+ uint64_t limit_high : 4;
+ uint64_t available : 1; // ???
+ uint64_t long_mode : 1;
+ uint64_t x32 : 1;
+ uint64_t gran : 1; // 1 - 4kb, 0 - 1b
+ uint64_t base_high : 8;
+} __attribute__((packed));
+
+struct tss_entry {
+ uint32_t reserved0;
+ uint64_t rsp[3];
+ uint64_t ist[8];
+ uint64_t reserved2;
+ uint16_t reserved3;
+ uint16_t iopb;
+} __attribute__((packed));
+
+struct lgdt_arg {
+ uint16_t limit;
+ uint32_t base;
+} __attribute__((packed));
+
+__attribute__((section(".shared")))
+struct gdt_entry GDT[SEG_end];
+__attribute__((section(".shared")))
+struct tss_entry TSS;
+
+struct lgdt_arg lgdt_arg;
+
+
+static void *memset32(void *s, int c, size_t n) {
+ uint8_t *s2 = s;
+ for (size_t i = 0; i < n; i++)
+ s2[i] = c;
+ return s;
+}
+
+
+static void gdt_fillout(struct gdt_entry* entry, uint8_t ring, bool code) {
+ *entry = (struct gdt_entry) {
+ // set up the identity mapping
+ .limit_low = 0xFFFF,
+ .limit_high = 0xF,
+ .gran = 1,
+ .base_low = 0,
+ .base_high = 0,
+
+ .ring = ring,
+ .code = code,
+
+ .accessed = 0,
+ .rw = 1,
+ .conforming = 0,
+ .codeordata = 1,
+ .present = 1,
+ .long_mode = 1,
+ .available = 1,
+ .x32 = 0,
+ };
+}
+
+void gdt_init(void) {
+ GDT[SEG_null].present = 0;
+
+ gdt_fillout(&GDT[SEG_r0code], 0, true);
+ gdt_fillout(&GDT[SEG_r0data], 0, false);
+ gdt_fillout(&GDT[SEG_r3code], 3, true);
+ gdt_fillout(&GDT[SEG_r3data], 3, false);
+
+ lgdt_arg.limit = sizeof(GDT) - 1;
+ lgdt_arg.base = (uint64_t) &GDT;
+
+
+ memset32(&TSS, 0, sizeof(TSS));
+ for (int i = 0; i < 3; i++)
+ TSS.rsp[i] = (uint64_t) &_isr_mini_stack;
+ TSS.ist[1] = (uint64_t) &_isr_mini_stack;
+
+ uint64_t tss_addr = (uint64_t) &TSS;
+ GDT[SEG_TSS] = (struct gdt_entry) {
+ .limit_low = sizeof(TSS),
+ .limit_high = sizeof(TSS) >> 16,
+ .gran = 0,
+ .base_low = tss_addr,
+ .base_high = tss_addr >> 24,
+
+ .accessed = 1,
+ .rw = 0,
+ .conforming = 0,
+ .code = 1,
+ .codeordata = 0,
+ .ring = 0, // was 3 pre-port
+ .present = 1,
+ .available = 1,
+ .long_mode = 0,
+ .x32 = 0,
+ };
+ *((uint64_t*)&GDT[SEG_TSS2]) = (tss_addr >> 32);
+}
diff --git a/src/kernel/arch/i386/gdt.h b/src/kernel/arch/amd64/32/gdt.h
index 5e40cd7..fbaf681 100644
--- a/src/kernel/arch/i386/gdt.h
+++ b/src/kernel/arch/amd64/32/gdt.h
@@ -8,6 +8,7 @@ enum {
SEG_r3code,
SEG_r3data,
SEG_TSS,
+ SEG_TSS2,
SEG_end
};
diff --git a/src/kernel/arch/amd64/32/paging.c b/src/kernel/arch/amd64/32/paging.c
new file mode 100644
index 0000000..975dd98
--- /dev/null
+++ b/src/kernel/arch/amd64/32/paging.c
@@ -0,0 +1,131 @@
+#include <stddef.h>
+#include <stdint.h>
+
+struct pml4e {
+ uint64_t present : 1;
+ uint64_t writeable : 1;
+ uint64_t user : 1;
+ uint64_t writethru : 1;
+
+ uint64_t uncached : 1;
+ uint64_t accessed : 1;
+ uint64_t _unused1 : 1;
+ uint64_t reserved : 1; // always 0
+
+ uint64_t _unused2 : 3;
+ uint64_t _unused3 : 1; // HLAT thing
+
+ uint64_t address : 40;
+
+ uint64_t _unused4 : 11;
+ uint64_t noexec : 1;
+} __attribute__((packed));
+
+struct pdpte { // page directory pointer table entry, 1gb page | 512 * pde
+ uint64_t present : 1;
+ uint64_t writeable : 1;
+ uint64_t user : 1;
+ uint64_t writethru : 1;
+
+ uint64_t uncached : 1;
+ uint64_t accessed : 1;
+ uint64_t _unused1 : 1;
+ uint64_t large : 1; // 1gb page
+
+ uint64_t _unused2 : 3;
+ uint64_t _unused3 : 1; // HLAT
+
+ uint64_t address : 40;
+
+ uint64_t _unused4 : 11;
+ uint64_t noexec : 1;
+} __attribute__((packed));
+
+struct pde { // page directory entry, 2mb page | 512 * pte
+ uint64_t present : 1;
+ uint64_t writeable : 1;
+ uint64_t user : 1;
+ uint64_t writethru : 1;
+
+ uint64_t uncached : 1;
+ uint64_t accessed : 1;
+ uint64_t dirty : 1; // only if large
+ uint64_t large : 1; // 2mb
+
+ uint64_t global : 1; // only if large ; TODO enable CR4.PGE
+ uint64_t _unused2 : 2;
+ uint64_t _unused3 : 1; // HLAT
+
+ uint64_t address : 40; // highest bit - PAT
+
+ uint64_t _unused4 : 7;
+ uint64_t pke : 4;
+ uint64_t noexec : 1;
+} __attribute__((packed));
+
+struct pte { // page table entry, 4kb page
+ uint64_t present : 1;
+ uint64_t writeable : 1;
+ uint64_t user : 1;
+ uint64_t writethru : 1;
+
+ uint64_t uncached : 1;
+ uint64_t accessed : 1;
+ uint64_t dirty : 1;
+ uint64_t pat : 1;
+
+ uint64_t global : 1; // TODO enable CR4.PGE
+ uint64_t _unused2 : 2;
+ uint64_t _unused3 : 1; // HLAT
+
+ uint64_t address : 40;
+
+ uint64_t _unused4 : 7;
+ uint64_t pke : 4;
+ uint64_t noexec : 1;
+} __attribute__((packed));
+
+__attribute__((aligned(4096)))
+struct pml4e pml4_identity[512];
+
+__attribute__((aligned(4096)))
+struct pdpte pdpte_low[512]; // 0-512gb
+
+__attribute__((aligned(4096)))
+struct pde pde_low[512]; // 0-1gb
+
+
+static void *memset32(void *s, int c, size_t n) {
+ uint8_t *s2 = s;
+ for (size_t i = 0; i < n; i++)
+ s2[i] = c;
+ return s;
+}
+
+
+void pml4_identity_init(void) {
+ memset32(pml4_identity, 0, sizeof pml4_identity);
+ memset32(pdpte_low, 0, sizeof pdpte_low);
+ memset32(pde_low, 0, sizeof pde_low);
+
+ pml4_identity[0] = (struct pml4e) {
+ .present = 1,
+ .writeable = 1,
+ .address = ((uintptr_t)pdpte_low) >> 12,
+ };
+
+ pdpte_low[0] = (struct pdpte) {
+ .present = 1,
+ .writeable = 1,
+ .address = ((uintptr_t)pde_low) >> 12,
+ };
+
+ for (int i = 0; i < 512; i++) {
+ pde_low[i] = (struct pde) {
+ .present = 1,
+ .writeable = 1,
+ .large = 1,
+ .address = (i * 2 * 1024 * 1024) >> 12,
+ };
+ }
+}
diff --git a/src/kernel/arch/i386/ata.c b/src/kernel/arch/amd64/ata.c
index 56344e4..371730e 100644
--- a/src/kernel/arch/i386/ata.c
+++ b/src/kernel/arch/amd64/ata.c
@@ -1,5 +1,5 @@
-#include <kernel/arch/i386/ata.h>
-#include <kernel/arch/i386/port_io.h>
+#include <kernel/arch/amd64/ata.h>
+#include <kernel/arch/amd64/port_io.h>
#include <kernel/panic.h>
#include <stdbool.h>
diff --git a/src/kernel/arch/i386/ata.h b/src/kernel/arch/amd64/ata.h
index 82f4f81..82f4f81 100644
--- a/src/kernel/arch/i386/ata.h
+++ b/src/kernel/arch/amd64/ata.h
diff --git a/src/kernel/arch/i386/boot.c b/src/kernel/arch/amd64/boot.c
index 754a327..0e61ed3 100644
--- a/src/kernel/arch/i386/boot.c
+++ b/src/kernel/arch/amd64/boot.c
@@ -1,36 +1,34 @@
#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/ata.h>
-#include <kernel/arch/i386/boot.h>
-#include <kernel/arch/i386/driver/fsroot.h>
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/gdt.h>
-#include <kernel/arch/i386/interrupts/idt.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/multiboot.h>
-#include <kernel/arch/i386/tty/tty.h>
+#include <kernel/arch/amd64/32/gdt.h>
+#include <kernel/arch/amd64/ata.h>
+#include <kernel/arch/amd64/boot.h>
+#include <kernel/arch/amd64/driver/fsroot.h>
+#include <kernel/arch/amd64/driver/ps2.h>
+#include <kernel/arch/amd64/driver/serial.h>
+#include <kernel/arch/amd64/interrupts/idt.h>
+#include <kernel/arch/amd64/interrupts/irq.h>
+#include <kernel/arch/amd64/multiboot.h>
+#include <kernel/arch/amd64/tty/tty.h>
#include <kernel/main.h>
#include <kernel/mem/alloc.h>
#include <kernel/panic.h>
static void find_init(struct multiboot_info *multiboot, struct kmain_info *info)
{
- struct multiboot_mod *module = &multiboot->mods[0];
+ struct multiboot_mod *module = (void*)multiboot->mods;
+ kprintf("mods count 0x%x", multiboot->mods_count);
if (multiboot->mods_count < 1) {
kprintf("can't find init! ");
panic_invalid_state();
}
info->init.at = module->start;
info->init.size = module->end - module->start;
-
}
void kmain_early(struct multiboot_info *multiboot) {
struct kmain_info info;
tty_init();
- kprintf("gdt...");
- gdt_init();
kprintf("idt...");
idt_init();
kprintf("irq...");
diff --git a/src/kernel/arch/i386/boot.h b/src/kernel/arch/amd64/boot.h
index 544f02d..98adff5 100644
--- a/src/kernel/arch/i386/boot.h
+++ b/src/kernel/arch/amd64/boot.h
@@ -1,4 +1,4 @@
#pragma once
-#include <kernel/arch/i386/multiboot.h>
+#include <kernel/arch/amd64/multiboot.h>
void kmain_early(struct multiboot_info *multiboot);
diff --git a/src/kernel/arch/amd64/boot64.s b/src/kernel/arch/amd64/boot64.s
new file mode 100644
index 0000000..1dca0ca
--- /dev/null
+++ b/src/kernel/arch/amd64/boot64.s
@@ -0,0 +1,13 @@
+.global boot64
+boot64:
+ lgdt (lgdt_arg) // try reloading gdt again
+ mov $(5 << 3 | 3), %ax // SEG_TSS
+ ltr %ax
+
+ xchgw %bx, %bx
+ push %rdi // preserve multiboot struct
+ call sysenter_setup
+ pop %rdi
+
+ // multiboot struct in %rdi
+ jmp kmain_early
diff --git a/src/kernel/arch/i386/debug.c b/src/kernel/arch/amd64/debug.c
index b1920db..52127da 100644
--- a/src/kernel/arch/i386/debug.c
+++ b/src/kernel/arch/amd64/debug.c
@@ -1,14 +1,14 @@
#include <kernel/arch/generic.h>
void *debug_caller(size_t depth) {
- void **ebp;
- asm("mov %%ebp, %0"
- : "=r" (ebp));
+ void **rbp;
+ asm("mov %%rbp, %0"
+ : "=r" (rbp));
while (depth--) {
- if (!ebp) return NULL;
- ebp = *ebp;
+ if (!rbp) return NULL;
+ rbp = *rbp;
}
- return ebp[1];
+ return rbp[1];
}
void debug_stacktrace(void) {
diff --git a/src/kernel/arch/i386/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c
index 8b1b307..02a4a21 100644
--- a/src/kernel/arch/i386/driver/fsroot.c
+++ b/src/kernel/arch/amd64/driver/fsroot.c
@@ -1,9 +1,9 @@
-#include <kernel/arch/i386/ata.h>
+#include <kernel/arch/amd64/ata.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
#include <kernel/util.h>
-#include <kernel/arch/i386/driver/fsroot.h>
+#include <kernel/arch/amd64/driver/fsroot.h>
#include <shared/mem.h>
#include <stdbool.h>
diff --git a/src/kernel/arch/i386/driver/fsroot.h b/src/kernel/arch/amd64/driver/fsroot.h
index dd72202..dd72202 100644
--- a/src/kernel/arch/i386/driver/fsroot.h
+++ b/src/kernel/arch/amd64/driver/fsroot.h
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/amd64/driver/ps2.c
index 341a7d3..8a5a078 100644
--- a/src/kernel/arch/i386/driver/ps2.c
+++ b/src/kernel/arch/amd64/driver/ps2.c
@@ -1,5 +1,5 @@
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/interrupts/irq.h>
+#include <kernel/arch/amd64/driver/ps2.h>
+#include <kernel/arch/amd64/interrupts/irq.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
#include <kernel/vfs/request.h>
diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/amd64/driver/ps2.h
index 54e8fb2..54e8fb2 100644
--- a/src/kernel/arch/i386/driver/ps2.h
+++ b/src/kernel/arch/amd64/driver/ps2.h
diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c
index dac5b75..6dda657 100644
--- a/src/kernel/arch/i386/driver/serial.c
+++ b/src/kernel/arch/amd64/driver/serial.c
@@ -1,6 +1,6 @@
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/port_io.h>
+#include <kernel/arch/amd64/driver/serial.h>
+#include <kernel/arch/amd64/interrupts/irq.h>
+#include <kernel/arch/amd64/port_io.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
#include <shared/container/ring.h>
diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/amd64/driver/serial.h
index 6a4876e..6a4876e 100644
--- a/src/kernel/arch/i386/driver/serial.h
+++ b/src/kernel/arch/amd64/driver/serial.h
diff --git a/src/kernel/arch/i386/interrupts/idt.c b/src/kernel/arch/amd64/interrupts/idt.c
index cd2adfd..9c71000 100644
--- a/src/kernel/arch/i386/interrupts/idt.c
+++ b/src/kernel/arch/amd64/interrupts/idt.c
@@ -1,26 +1,28 @@
-#include <kernel/arch/i386/gdt.h>
-#include <kernel/arch/i386/interrupts/idt.h>
-#include <kernel/arch/i386/interrupts/isr.h>
+#include <kernel/arch/amd64/32/gdt.h>
+#include <kernel/arch/amd64/interrupts/idt.h>
+#include <kernel/arch/amd64/interrupts/isr.h>
#include <kernel/panic.h>
#include <stdbool.h>
#include <stdint.h>
struct idt_entry {
- uint16_t offset_low ;
- uint16_t code_seg ;
- uint8_t zero ; // unused, has to be 0
- uint8_t type : 4; // 16/32 bit, task/interrupt/task gate
- uint8_t storage : 1; // 0 for interrupt/trap gates
- uint8_t ring : 2;
- uint8_t present : 1;
- uint16_t offset_high ;
+ uint16_t offset_low;
+ uint16_t seg;
+ uint8_t ist;
+ uint8_t type : 4; // 0xE - interrupt, 0xF - trap
+ uint8_t zero1 : 1;
+ uint8_t ring : 2;
+ uint8_t present : 1;
+ uint16_t offset_mid;
+ uint32_t offset_high;
+ uint32_t zero2;
} __attribute__((packed));
// is exactly the same as lgdt_arg, i should combine them into a single struct
// later
struct lidt_arg {
uint16_t limit;
- uint32_t base;
+ uintptr_t base;
} __attribute__((packed));
__attribute__((section(".shared")))
@@ -33,19 +35,17 @@ static void idt_test(void);
static void idt_prepare(void) {
- uintptr_t offset;
for (int i = 0; i < 256; i++) {
- offset = (uintptr_t) &_isr_stubs + i * 8;
+ uintptr_t offset = (uintptr_t) &_isr_stubs + i * 8;
IDT[i] = (struct idt_entry) {
.offset_low = offset,
- .offset_high = offset >> 16,
- .code_seg = SEG_r0code << 3,
- .zero = 0,
- .present = 1,
- .ring = 0,
- .storage = 0,
- .type = 0xE, // 32-bit interrupt gate
+ .offset_mid = offset >> 16,
+ .offset_high = offset >> 32,
+ .seg = SEG_r0code << 3,
+ .present = 1,
+ .type = 0xE,
+ .ist = 1,
};
}
}
@@ -57,8 +57,11 @@ static void idt_load(void) {
}
static void idt_test(void) {
+ kprintf("idt test?\n");
+ asm("xchgw %%bx, %%bx" ::: "memory");
asm("int $0x34" : : : "memory");
assert(isr_test_interrupt_called);
+ kprintf("done.\n");
}
void idt_init(void) {
diff --git a/src/kernel/arch/i386/interrupts/idt.h b/src/kernel/arch/amd64/interrupts/idt.h
index 6576cf9..6576cf9 100644
--- a/src/kernel/arch/i386/interrupts/idt.h
+++ b/src/kernel/arch/amd64/interrupts/idt.h
diff --git a/src/kernel/arch/i386/interrupts/irq.c b/src/kernel/arch/amd64/interrupts/irq.c
index 5918169..74bc48c 100644
--- a/src/kernel/arch/i386/interrupts/irq.c
+++ b/src/kernel/arch/amd64/interrupts/irq.c
@@ -1,5 +1,5 @@
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/port_io.h>
+#include <kernel/arch/amd64/interrupts/irq.h>
+#include <kernel/arch/amd64/port_io.h>
#include <stdint.h>
static const int PIC1 = 0x20;
diff --git a/src/kernel/arch/i386/interrupts/irq.h b/src/kernel/arch/amd64/interrupts/irq.h
index f523154..f523154 100644
--- a/src/kernel/arch/i386/interrupts/irq.h
+++ b/src/kernel/arch/amd64/interrupts/irq.h
diff --git a/src/kernel/arch/i386/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c
index 2d893cb..b55bc8b 100644
--- a/src/kernel/arch/i386/interrupts/isr.c
+++ b/src/kernel/arch/amd64/interrupts/isr.c
@@ -1,8 +1,8 @@
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/interrupts/isr.h>
-#include <kernel/arch/i386/port_io.h>
+#include <kernel/arch/amd64/driver/ps2.h>
+#include <kernel/arch/amd64/driver/serial.h>
+#include <kernel/arch/amd64/interrupts/irq.h>
+#include <kernel/arch/amd64/interrupts/isr.h>
+#include <kernel/arch/amd64/port_io.h>
#include <kernel/arch/generic.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
@@ -11,12 +11,22 @@
bool isr_test_interrupt_called = false;
-void isr_stage3(int interrupt) {
+void isr_stage3(int interrupt, uint64_t *stackframe) {
+ if (interrupt == 0xe) stackframe++;
+ kprintf("interrupt %x, rip = k/%08x, cs 0x%x\n", interrupt, stackframe[0], stackframe[1]);
switch (interrupt) {
case 0x08: // double fault
kprintf("#DF");
panic_invalid_state();
+
+ case 0xe:
+ uint64_t addr = 0x69;
+ asm("mov %%cr2, %0" : "=r"(addr));
+ kprintf("error code 0x%x, addr 0x%x\n", stackframe[-1], addr);
+ panic_unimplemented();
+
case 0x34:
+ asm("nop" ::: "memory");
isr_test_interrupt_called = true;
return;
diff --git a/src/kernel/arch/i386/interrupts/isr.h b/src/kernel/arch/amd64/interrupts/isr.h
index 3189538..01f5236 100644
--- a/src/kernel/arch/i386/interrupts/isr.h
+++ b/src/kernel/arch/amd64/interrupts/isr.h
@@ -1,7 +1,8 @@
#pragma once
#include <stdbool.h>
+#include <stdint.h>
extern bool isr_test_interrupt_called; // used in the self-test in idt.c
extern const char _isr_stubs;
-void isr_stage3(int interrupt);
+void isr_stage3(int interrupt, uint64_t *stackframe);
diff --git a/src/kernel/arch/amd64/interrupts/isr_stub.s b/src/kernel/arch/amd64/interrupts/isr_stub.s
new file mode 100644
index 0000000..e45c1c1
--- /dev/null
+++ b/src/kernel/arch/amd64/interrupts/isr_stub.s
@@ -0,0 +1,81 @@
+.section .shared
+
+.global _isr_stubs
+_isr_stubs:
+.rept 256
+ .set _stub_start, .
+
+ cli
+ call _isr_stage2
+
+ .if . - _stub_start > 8
+ .error "isr stubs over maximum size"
+ .abort
+ .endif
+ .align 8
+.endr
+
+_isr_stage2:
+ // pushal order, without %esp
+ push %rax
+ push %rcx
+ push %rdx
+ push %rbx
+ push %rbp
+ push %rsi
+ push %rdi
+ push %r8
+ push %r9
+ push %r10
+ push %r11
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ // convert the return address into the vector nr
+ mov 120(%rsp), %rdi
+ sub $_isr_stubs, %rdi
+ shr $3, %rdi
+
+ lea 128(%rsp), %rsi // second argument - IRET stack frame
+
+ // load kernel paging
+ mov %cr3, %rbx
+ push %rbx
+ mov $pml4_identity, %rbx
+ mov %rbx, %cr3
+
+ mov %rsp, %rbp
+ mov $_isr_big_stack, %rsp
+ call isr_stage3
+
+ mov %rbp, %rsp
+ pop %rax // restore old cr3
+ mov %rax, %cr3
+
+ // restore registers
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %r11
+ pop %r10
+ pop %r9
+ pop %r8
+ pop %rdi
+ pop %rsi
+ pop %rbp
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rax
+
+ add $8, %rsp // skip call's return address
+ iretq
+
+.align 8
+// TODO overflow check
+.skip 256 // seems to be enough
+.global _isr_mini_stack
+_isr_mini_stack:
diff --git a/src/kernel/arch/i386/multiboot.h b/src/kernel/arch/amd64/multiboot.h
index 1d6718f..c6a2650 100644
--- a/src/kernel/arch/i386/multiboot.h
+++ b/src/kernel/arch/amd64/multiboot.h
@@ -1,15 +1,10 @@
#pragma once
#include <stdint.h>
-#ifndef __CHECKER__
-_Static_assert(sizeof(void*) == 4,
- "this code assumes that pointers have 4 bytes");
-#endif
-
struct multiboot_mod {
- void *start;
- void *end;
- const char *str;
+ uint32_t start;
+ uint32_t end;
+ uint32_t str;
uint32_t _reserved;
} __attribute__((packed));
@@ -19,16 +14,16 @@ struct multiboot_info {
uint32_t flag_cmdline : 1;
uint32_t flag_mods : 1;
uint32_t _flag_other : 28; // unimplemented
-
+
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
- const char *cmdline;
+ uint32_t cmdline;
uint32_t mods_count;
- struct multiboot_mod *mods;
+ uint32_t mods;
// [...]
} __attribute__((packed));
diff --git a/src/kernel/arch/i386/multiboot.s b/src/kernel/arch/amd64/multiboot.s
index dc19b36..dc19b36 100644
--- a/src/kernel/arch/i386/multiboot.s
+++ b/src/kernel/arch/amd64/multiboot.s
diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/amd64/pagedir.c
index e607cc7..334cfc2 100644
--- a/src/kernel/arch/i386/pagedir.c
+++ b/src/kernel/arch/amd64/pagedir.c
@@ -90,15 +90,20 @@ void *pagedir_unmap(struct pagedir *dir, void __user *virt) {
void pagedir_map(struct pagedir *dir, void __user *virt, void *phys,
bool user, bool writeable)
{
+ kprintf("in pagedir_map, dir 0x%x\n", dir);
uintptr_t virt_cast = (uintptr_t) virt;
uint32_t pd_idx = virt_cast >> 22;
uint32_t pt_idx = virt_cast >> 12 & 0x03FF;
struct pagetable_entry *pagetable;
+ kprintf("pre-if, accessing 0x%x because 0x%x\n", &dir->e[pd_idx], pd_idx);
if (dir->e[pd_idx].present) {
+ kprintf("present already\n");
pagetable = (void*) (dir->e[pd_idx].address << 11);
} else {
+ kprintf("allocing\n");
pagetable = page_alloc(1);
+ kprintf("alloc successful\n");
for (int i = 0; i < 1024; i++)
pagetable[i].present = 0;
@@ -128,10 +133,12 @@ void pagedir_map(struct pagedir *dir, void __user *virt, void *phys,
._unused = 0,
.address = (uintptr_t) phys >> 11
};
+ kprintf("out pagedir_map\n");
}
+extern void *pagedir_current;
void pagedir_switch(struct pagedir *dir) {
- asm volatile("mov %0, %%cr3;" : : "r" (dir) : "memory");
+ pagedir_current = dir;
}
// creates a new pagedir with exact copies of the user pages
diff --git a/src/kernel/arch/i386/port_io.h b/src/kernel/arch/amd64/port_io.h
index eac9331..eac9331 100644
--- a/src/kernel/arch/i386/port_io.h
+++ b/src/kernel/arch/amd64/port_io.h
diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/amd64/registers.h
index 9f481d3..e365e2c 100644
--- a/src/kernel/arch/i386/registers.h
+++ b/src/kernel/arch/amd64/registers.h
@@ -3,19 +3,16 @@
#include <stdint.h>
struct registers {
- /* those are in the order of pushad/popad - so you can load/save this
- * struct in (almost) one instruction */
- uint32_t edi, esi;
+ uint64_t edi, esi;
userptr_t ebp, esp;
- uint32_t ebx, edx, ecx, eax;
+ uint64_t ebx, edx, ecx, eax;
- // not part of pushad/popad, but still useful
userptr_t eip;
} __attribute__((__packed__));
// saves a return value according to the SysV ABI
static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) {
regs->eax = value;
- regs->edx = value >> 32;
+ regs->edx = value >> 32; // TODO check ABI
return value;
}
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/amd64/sysenter.c
index 5837474..e42ec7d 100644
--- a/src/kernel/arch/i386/sysenter.c
+++ b/src/kernel/arch/amd64/sysenter.c
@@ -1,5 +1,5 @@
#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/sysenter.h>
+#include <kernel/arch/amd64/sysenter.h>
#include <kernel/proc.h>
#include <shared/syscalls.h>
@@ -14,6 +14,7 @@ void sysexit(struct registers regs) {
}
_Noreturn void sysenter_stage2(void) {
+ kprintf("ring0 again!\n");
struct registers *regs = &process_current->regs;
*regs = _sysexit_regs; // save the registers
diff --git a/src/kernel/arch/i386/sysenter.h b/src/kernel/arch/amd64/sysenter.h
index b88c186..b88c186 100644
--- a/src/kernel/arch/i386/sysenter.h
+++ b/src/kernel/arch/amd64/sysenter.h
diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/amd64/sysenter.s
index d04f839..4dfe19d 100644
--- a/src/kernel/arch/i386/sysenter.s
+++ b/src/kernel/arch/amd64/sysenter.s
@@ -1,4 +1,4 @@
-/* arch/i386/gdt.c */
+/* TODO include gdt.h */
.set SEG_r0code, 1
.set SEG_r3code, 3
.set SEG_r3data, 4
@@ -11,18 +11,18 @@
.global sysenter_setup
.type sysenter_setup, @function
sysenter_setup:
- xor %edx, %edx
+ xor %rdx, %rdx
- mov $(SEG_r0code << 3), %eax
- mov $IA32_SYSENTER_CS, %ecx
+ mov $(SEG_r0code << 3), %rax
+ mov $IA32_SYSENTER_CS, %rcx
wrmsr
- mov $IA32_SYSENTER_ESP, %ecx
- mov $0, %eax // unused
+ mov $IA32_SYSENTER_ESP, %rcx
+ mov $0, %rax // unused
wrmsr
- mov $IA32_SYSENTER_EIP, %ecx
- mov $sysenter_stage1, %eax
+ mov $IA32_SYSENTER_EIP, %rcx
+ mov $sysenter_stage1, %rax
wrmsr
ret
@@ -34,9 +34,15 @@ sysenter_setup:
stored_eax:
.long 0
+.global pagedir_current
+// a hack to maintain compat with the old arch api, TODO
+pagedir_current:
+.long 0
+
.global _sysexit_real
.type _sysexit_real, @function
_sysexit_real:
+ xchgw %bx, %bx
mov $(SEG_r3data << 3 | 3), %ax
mov %ax, %ds
mov %ax, %es
@@ -44,46 +50,44 @@ _sysexit_real:
mov %ax, %gs
// restore the registers
- mov $_sysexit_regs, %esp
- pop %edi
- pop %esi
- pop %ebp
- add $4, %esp
- pop %ebx
- pop %edx
- pop %ecx
- pop %eax
+ mov $_sysexit_regs, %rsp
+ pop %rdi
+ pop %rsi
+ pop %rbp
+ add $8, %rsp
+ pop %rbx
+ pop %rdx
+ pop %rcx
+ pop %rax
// enable paging
- mov %eax, stored_eax
- mov %cr0, %eax
- or $0x80000000, %eax
- mov %eax, %cr0
- mov stored_eax, %eax
-
+ // %rsp used as a scratch register
+ mov (pagedir_current), %rsp
+ mov %rsp, %cr3
sysexit
sysenter_stage1:
cli /* prevent random IRQs in the middle of kernel code */
+ xchgw %bx, %bx
// disable paging
// I don't want to damage any of the registers passed in by the user,
// so i'm using ESP as a temporary register. At this point there's nothing
// useful in it, it's == _bss_end.
- mov %cr0, %esp
- and $0x7FFFFFFF, %esp // disable paging
- mov %esp, %cr0
+ mov %cr0, %rsp
+ and $0x7FFFFFFF, %rsp // disable paging
+ mov %rsp, %cr0
// save the registers
- mov $(_sysexit_regs + 32), %esp
- push %eax
- push %ecx
- push %edx
- push %ebx
- push $0x0 // pushal pushes %esp here, but that's worthless
- push %ebp
- push %esi
- push %edi
-
- mov $_bss_end, %esp
+ mov $(_sysexit_regs + 64), %rsp
+ push %rax
+ push %rcx
+ push %rdx
+ push %rbx
+ push $0x0 // pushal pushes %rsp here, but that's worthless
+ push %rbp
+ push %rsi
+ push %rdi
+
+ mov $_bss_end, %rsp
jmp sysenter_stage2
diff --git a/src/kernel/arch/i386/tty/tty.c b/src/kernel/arch/amd64/tty/tty.c
index 9451059..6593ef6 100644
--- a/src/kernel/arch/i386/tty/tty.c
+++ b/src/kernel/arch/amd64/tty/tty.c
@@ -1,6 +1,6 @@
#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/tty/tty.h>
+#include <kernel/arch/amd64/driver/serial.h>
+#include <kernel/arch/amd64/tty/tty.h>
#include <shared/printf.h>
void tty_init(void) {
diff --git a/src/kernel/arch/i386/tty/tty.h b/src/kernel/arch/amd64/tty/tty.h
index b96003d..b96003d 100644
--- a/src/kernel/arch/i386/tty/tty.h
+++ b/src/kernel/arch/amd64/tty/tty.h
diff --git a/src/kernel/arch/i386/tty/vga.c b/src/kernel/arch/amd64/tty/vga.c
index 9efd326..e5f2274 100644
--- a/src/kernel/arch/i386/tty/vga.c
+++ b/src/kernel/arch/amd64/tty/vga.c
@@ -1,4 +1,4 @@
-#include <kernel/arch/i386/tty/tty.h>
+#include <kernel/arch/amd64/tty/tty.h>
struct vga_cell {
unsigned char c;
diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h
index a9e1ac9..d1ff292 100644
--- a/src/kernel/arch/generic.h
+++ b/src/kernel/arch/generic.h
@@ -1,6 +1,6 @@
#pragma once
-#include <kernel/arch/i386/registers.h>
+#include <kernel/arch/amd64/registers.h>
#include <shared/types.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -15,7 +15,7 @@
extern char _bss_end;
__attribute__((noreturn))
-void halt_cpu(void);
+void cpu_halt(void);
__attribute__((noreturn))
void cpu_shutdown(void);
diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s
deleted file mode 100644
index 743c6d6..0000000
--- a/src/kernel/arch/i386/boot.s
+++ /dev/null
@@ -1,34 +0,0 @@
-.section .text
-.global _start
-.type _start, @function
-_start:
- mov $_stack_top, %esp
- call sysenter_setup
- push %ebx // address of the Multiboot struct
- call kmain_early
-
-.global cpu_shutdown
-.type cpu_shutdown, @function
-cpu_shutdown:
-/* This quits QEMU. While I couldn't find this officially documented anywhere,
- * it is used by QEMU in tests/tcg/i386/system/boot.S (as of commit 40d6ee), so
- * I assume that this is safe-ish to use */
- mov $0x604, %edx
- mov $0x2000, %eax
- outw %ax, %dx
-
-.global halt_cpu
-.type halt_cpu, @function
-halt_cpu:
- cli
-1: hlt
- jmp 1b
-
-
-.global cpu_pause
-.type cpu_pause, @function
-cpu_pause:
- sti
- hlt
- cli
- ret
diff --git a/src/kernel/arch/i386/interrupts/isr_stub.s b/src/kernel/arch/i386/interrupts/isr_stub.s
deleted file mode 100644
index fdbae6f..0000000
--- a/src/kernel/arch/i386/interrupts/isr_stub.s
+++ /dev/null
@@ -1,64 +0,0 @@
-.section .shared
-
-.global _isr_stubs
-_isr_stubs:
-.rept 256
- .set _stub_start, .
-
- cli
- call _isr_stage2
-
- .if . - _stub_start > 8
- .error "isr stubs over maximum size"
- .abort
- .endif
- .align 8
-.endr
-
-_isr_stage2:
- // pushal order, without %esp
- push %eax
- push %ecx
- push %edx
- push %ebx
- push %ebp
- push %esi
- push %edi
-
- // convert the return address into the vector nr
- mov 28(%esp), %eax
- add $-_isr_stubs, %eax
- shr $3, %eax
-
- // disable paging, if present
- mov %cr0, %ebx
- push %ebx // push original cr0
- and $0x7FFFFFFF, %ebx
- mov %ebx, %cr0
-
- mov %esp, %ebp
- mov $_isr_big_stack, %esp
- push %eax // push the vector nr
- call isr_stage3
-
- mov %ebp, %esp
- pop %eax // restore old cr0
- mov %eax, %cr0
-
- // restore registers
- pop %edi
- pop %esi
- pop %ebp
- pop %ebx
- pop %edx
- pop %ecx
- pop %eax
-
- add $4, %esp // skip call's return address
- iret
-
-.align 8
-// TODO overflow check
-.skip 64 // seems to be enough
-.global _isr_mini_stack
-_isr_mini_stack:
diff --git a/src/kernel/panic.h b/src/kernel/panic.h
index 8cb32f4..4e591f1 100644
--- a/src/kernel/panic.h
+++ b/src/kernel/panic.h
@@ -7,7 +7,7 @@
kprintf(__func__); \
kprintf(" (" __FILE__ ":" NUM2STR(__LINE__) ")\n"); \
debug_stacktrace(); \
- halt_cpu(); \
+ cpu_halt(); \
} while (0)
#define panic_invalid_state() _panic("invalid state")
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 1cb6eb0..616bd79 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -196,6 +196,7 @@ void process_forget(struct process *p) {
}
static _Noreturn void process_switch(struct process *proc) {
+ kprintf("process_switch\n");
assert(proc->state == PS_RUNNING);
process_current = proc;
pagedir_switch(proc->pages);
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 7c677cc..97c71a7 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -1,4 +1,4 @@
-#include <kernel/arch/i386/driver/fsroot.h>
+#include <kernel/arch/amd64/driver/fsroot.h>
#include <kernel/mem/alloc.h>
#include <kernel/mem/virt.h>
#include <kernel/panic.h>
diff --git a/src/shared/printf.c b/src/shared/printf.c
index 496d5b8..b50d4ef 100644
--- a/src/shared/printf.c
+++ b/src/shared/printf.c
@@ -47,9 +47,9 @@ modifier_break:
break;
case 'x':
- unsigned int n = va_arg(argp, int);
+ unsigned long n = va_arg(argp, long);
size_t i = 4; // nibbles * 4
- while (n >> i && i < (sizeof(int) * 8))
+ while (n >> i && i < (sizeof(n) * 8))
i += 4;
if (i < pad_len * 4)
diff --git a/src/user/lib/syscall.s b/src/user/lib/syscall.s
index 0af49f3..0f9e444 100644
--- a/src/user/lib/syscall.s
+++ b/src/user/lib/syscall.s
@@ -2,23 +2,24 @@
.global _syscall
.type _syscall, @function
_syscall:
- push %ebx // preserve registers
- push %esi
- push %edi
- push %ebp
+ push %rbx // preserve registers
+ push %rsi
+ push %rdi
+ push %rbp
- mov 20(%esp), %eax
- mov 24(%esp), %ebx
- mov %esp, %ecx
- mov $_syscall_ret, %edx
- mov 28(%esp), %esi
- mov 32(%esp), %edi
- mov 36(%esp), %ebp
+ // NOT the calling convention TODO you lazy fuck
+ mov 20(%rsp), %rax
+ mov 24(%rsp), %rbx
+ mov %rsp, %rcx
+ mov $_syscall_ret, %rdx
+ mov 28(%rsp), %rsi
+ mov 32(%rsp), %rdi
+ mov 36(%rsp), %rbp
sysenter
_syscall_ret:
- pop %ebp
- pop %edi
- pop %esi
- pop %ebx
+ pop %rbp
+ pop %rdi
+ pop %rsi
+ pop %rbx
ret