summaryrefslogtreecommitdiff
path: root/src/kernel/arch
diff options
context:
space:
mode:
authordzwdz2022-07-16 22:50:34 +0200
committerdzwdz2022-07-16 22:50:34 +0200
commita251c14f1a745f3388ce73a5a45ebc73cd1782b5 (patch)
tree2eab140ce2bcc729d8836e97a61bd0d731bb44d6 /src/kernel/arch
parentc8ed6aa7476b7f506366d9fe56ed6f2e7a12b40d (diff)
amd64: back at the shell!
Diffstat (limited to 'src/kernel/arch')
-rw-r--r--src/kernel/arch/amd64/32/boot.s1
-rw-r--r--src/kernel/arch/amd64/32/gdt.c8
-rw-r--r--src/kernel/arch/amd64/boot.c6
-rw-r--r--src/kernel/arch/amd64/driver/fsroot.c2
-rw-r--r--src/kernel/arch/amd64/interrupts/isr.c19
-rw-r--r--src/kernel/arch/amd64/pagedir.c45
-rw-r--r--src/kernel/arch/amd64/sysenter.s11
7 files changed, 47 insertions, 45 deletions
diff --git a/src/kernel/arch/amd64/32/boot.s b/src/kernel/arch/amd64/32/boot.s
index 06de66e..af32007 100644
--- a/src/kernel/arch/amd64/32/boot.s
+++ b/src/kernel/arch/amd64/32/boot.s
@@ -80,6 +80,7 @@ cpu_halt:
.global cpu_pause
.type cpu_pause, @function
cpu_pause:
+ xchgw %bx, %bx
sti
hlt
cli
diff --git a/src/kernel/arch/amd64/32/gdt.c b/src/kernel/arch/amd64/32/gdt.c
index 2229330..d3d4aed 100644
--- a/src/kernel/arch/amd64/32/gdt.c
+++ b/src/kernel/arch/amd64/32/gdt.c
@@ -87,15 +87,15 @@ void gdt_init(void) {
gdt_fillout(&GDT[SEG_r3data], 3, false);
lgdt_arg.limit = sizeof(GDT) - 1;
- lgdt_arg.base = (uint64_t) &GDT;
+ lgdt_arg.base = (uint64_t)(int)&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;
+ TSS.rsp[i] = (uint64_t)(int)&_isr_mini_stack;
+ TSS.ist[1] = (uint64_t)(int)&_isr_mini_stack;
- uint64_t tss_addr = (uint64_t) &TSS;
+ uint64_t tss_addr = (uint64_t)(int)&TSS;
GDT[SEG_TSS] = (struct gdt_entry) {
.limit_low = sizeof(TSS),
.limit_high = sizeof(TSS) >> 16,
diff --git a/src/kernel/arch/amd64/boot.c b/src/kernel/arch/amd64/boot.c
index 0e61ed3..56cf8c8 100644
--- a/src/kernel/arch/amd64/boot.c
+++ b/src/kernel/arch/amd64/boot.c
@@ -15,13 +15,13 @@
static void find_init(struct multiboot_info *multiboot, struct kmain_info *info)
{
- struct multiboot_mod *module = (void*)multiboot->mods;
+ struct multiboot_mod *module = (void*)(long)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.at = (void*)(long)module->start;
info->init.size = module->end - module->start;
}
@@ -34,7 +34,7 @@ void kmain_early(struct multiboot_info *multiboot) {
kprintf("irq...");
irq_init();
- info.memtop = (void*) (multiboot->mem_upper * 1024);
+ info.memtop = (void*)(long)(multiboot->mem_upper * 1024);
find_init(multiboot, &info);
kprintf("mem...\n");
mem_init(&info);
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c
index 02a4a21..e651c47 100644
--- a/src/kernel/arch/amd64/driver/fsroot.c
+++ b/src/kernel/arch/amd64/driver/fsroot.c
@@ -45,7 +45,7 @@ static void req_preprocess(struct vfs_request *req, size_t max_len) {
static int handle(struct vfs_request *req) {
assert(req->caller);
- int id = (int)req->id;
+ int id = (int)(long)req->id;
switch (req->type) {
case VFSOP_OPEN:
if (exacteq(req, "/")) return HANDLE_ROOT;
diff --git a/src/kernel/arch/amd64/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c
index 4df8e57..bd560f5 100644
--- a/src/kernel/arch/amd64/interrupts/isr.c
+++ b/src/kernel/arch/amd64/interrupts/isr.c
@@ -11,20 +11,19 @@
bool isr_test_interrupt_called = false;
-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]);
+static void log_interrupt(int interrupt, uint64_t *stackframe) {
+ kprintf("interrupt %x, rip = k/%08x, cs 0x%x, code 0x%x\n",
+ interrupt, stackframe[0], stackframe[1], stackframe[-1]);
if (interrupt == 0xe) {
uint64_t addr = 0x69;
asm("mov %%cr2, %0" : "=r"(addr));
- kprintf("error code 0x%x, addr 0x%x\n", stackframe[-1], addr);
+ kprintf("addr 0x%x\n", addr);
}
+}
+void isr_stage3(int interrupt, uint64_t *stackframe) {
+ if (interrupt == 0xe || interrupt == 0xd) stackframe++;
switch (interrupt) {
- case 0x08: // double fault
- kprintf("#DF");
- panic_invalid_state();
-
case 0x34:
asm("nop" ::: "memory");
isr_test_interrupt_called = true;
@@ -41,8 +40,8 @@ void isr_stage3(int interrupt, uint64_t *stackframe) {
return;
default:
- if (stackframe[1] & 0x3 == 0) {
- kprintf("bye o7\n");
+ if ((stackframe[1] & 0x3) == 0) {
+ log_interrupt(interrupt, stackframe);
cpu_halt();
} else {
process_kill(process_current, interrupt);
diff --git a/src/kernel/arch/amd64/pagedir.c b/src/kernel/arch/amd64/pagedir.c
index 0d6078b..2075aac 100644
--- a/src/kernel/arch/amd64/pagedir.c
+++ b/src/kernel/arch/amd64/pagedir.c
@@ -69,35 +69,39 @@ struct pagedir *pagedir_new(void) {
}
void pagedir_free(struct pagedir *dir) {
- (void)dir;
- panic_unimplemented();
- /*
- // assumes all user pages are unique and can be freed
- struct pagetable_entry *pt;
- void *page;
-
- for (int i = 0; i < 1024; i++) {
+ for (int i = 0; i < 512; i++) {
if (!dir->e[i].present) continue;
+ assert(!dir->e[i].large);
+ pe_generic_t *pdpt = addr_extract(dir->e[i]);
- pt = (void*)(dir->e[i].address << 11);
+ for (int j = 0; j < 512; j++) {
+ if (!pdpt[j].present) continue;
+ assert(!pdpt[j].large);
+ pe_generic_t *pd = addr_extract(pdpt[j]);
- for (int j = 0; j < 1024; j++) {
- if (!pt[j].present) continue;
- if (!pt[j].user) continue;
+ for (int k = 0; k < 512; k++) {
+ if (!pd[k].present) continue;
+ assert(!pd[k].large);
+ pe_generic_t *pt = addr_extract(pd[k]);
- page = (void*)(pt[j].address << 11);
- page_free(page, 1);
+ for (int l = 0; l < 512; l++) {
+ if (!pt[l].present) continue;
+ if (!pt[l].user) continue;
+ page_free(addr_extract(pt[l]), 1);
+ }
+ page_free(pt, 1);
+ }
+ page_free(pd, 1);
}
- page_free(pt, 1);
+ page_free(pdpt, 1);
}
page_free(dir, 1);
- */
}
static pe_generic_t*
get_entry(struct pagedir *dir, const void __user *virt) {
pe_generic_t *pml4e, *pdpte, *pde, *pte;
- const union virt_addr v = {.full = (void*)virt};
+ const union virt_addr v = {.full = (void __user *)virt};
// TODO check if sign extension is valid
@@ -208,11 +212,12 @@ struct pagedir *pagedir_copy(const struct pagedir *pml4_old) {
pd_new[k].address = (uintptr_t) pt_new >> 12;
for (int l = 0; l < 512; l++) {
- if (!pt_old[l].present || !pt_old[l].user)
- continue;
+ if (!pt_old[l].present) continue;
+ pt_new[l] = pt_old[l];
+
+ if (!pt_old[l].user) continue;
void *page_new = page_alloc(1);
memcpy(page_new, addr_extract(pt_old[l]), PAGE_SIZE);
- pt_new[l] = pt_old[l];
pt_new[l].address = (uintptr_t) page_new >> 12;
}
}
diff --git a/src/kernel/arch/amd64/sysenter.s b/src/kernel/arch/amd64/sysenter.s
index 74db018..3f035dc 100644
--- a/src/kernel/arch/amd64/sysenter.s
+++ b/src/kernel/arch/amd64/sysenter.s
@@ -12,15 +12,16 @@
.global sysenter_setup
.type sysenter_setup, @function
sysenter_setup:
- xor %rdx, %rdx
// the intel docs don't mention the lower 32 bits
- mov $( ((SEG_r3code << 3 | 3) << 48) | ((SEG_r0code << 3) << 32) ), %rax
+ mov $0, %eax
+ mov $( ((SEG_r3code << 3 | 3) << 16) | (SEG_r0code << 3) ), %edx
mov $IA32_STAR, %rcx
wrmsr
+ mov $sysenter_stage1, %eax
+ mov $0, %edx
mov $IA32_LSTAR, %rcx
- mov $sysenter_stage1, %rax
wrmsr
// hoping that the default RFLAGS mask is fine...
@@ -50,8 +51,6 @@ _sysexit_real:
mov %ax, %gs
*/
- xchgw %bx, %bx
-
mov $_sysexit_regs, %rsp
pop %r15
pop %r14
@@ -77,12 +76,10 @@ _sysexit_real:
mov (pagedir_current), %rsp
mov %rsp, %cr3
mov (stored_rsp), %rsp
- nop
sysretq
sysenter_stage1:
cli
- xchgw %bx, %bx
mov %rsp, (stored_rsp)