diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/hal/obj.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/process.c | 37 | ||||
| -rw-r--r-- | arch/x86_64/hal/process.h | 14 | ||||
| -rw-r--r-- | arch/x86_64/hal/smp.c | 8 | ||||
| -rw-r--r-- | arch/x86_64/hal/smp.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/lib/elf.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/sys/init.c | 40 | ||||
| -rw-r--r-- | arch/x86_64/sys/serial.c | 41 | ||||
| -rw-r--r-- | arch/x86_64/sys/syscall.c | 40 | ||||
| -rw-r--r-- | arch/x86_64/sys/syscall.h | 23 |
10 files changed, 162 insertions, 47 deletions
diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h index f7d7711..78d7383 100644 --- a/arch/x86_64/hal/obj.h +++ b/arch/x86_64/hal/obj.h @@ -7,7 +7,7 @@ enum { - JOVE_OBJ_SERIAL_COM = 0x81, + JOVE_OBJ_SERIAL_COM = 0x80, }; /*Represents a locked kernel object pointer inside of a object directory.*/ diff --git a/arch/x86_64/hal/process.c b/arch/x86_64/hal/process.c index 5c91238..872be5a 100644 --- a/arch/x86_64/hal/process.c +++ b/arch/x86_64/hal/process.c @@ -1,6 +1,8 @@ #include "process.h" #include "arch/x86_64/hal/obj.h" #include "hal/obj.h" +#include "hal/process.h" +#include "hal/smp.h" #include "init.h" #include "smp.h" #include "paging.h" @@ -9,22 +11,53 @@ PAGEALIGN char s_init_pcb_bytes[0x1000] = { 0 }; static pcb_t *s_init_pcb = (pcb_t*)&s_init_pcb_bytes; +jove_owned_obj_t* +process_current(void) +{ + return obj_take(((processor_t*)processor_current())->pcb_obj); +} + +pcb_t* +pcb_from_obj(jove_owned_obj_t *obj) +{ + if(obj_gettype(obj) != JOVE_OBJ_PROCESS) { + reterr(EBADOBJ); + } + return obj_deref(obj); +} + +pid_t +pcb_pid(pcb_t *pcb) +{ + return pcb->pid; +} + +jove_owned_obj_t* +pcb_rootdir(pcb_t *pcb) +{ + return obj_take(pcb->rootdir); +} + void processing_setup(void (*process_main)) { uintptr_t ksp = ((uintptr_t)&s_init_pcb_bytes) + 0xFF0; + + s_init_pcb->pid = 1; s_init_pcb->ksp = (void*)ksp; s_init_pcb->pml4 = paging_get_pml4(); + s_init_pcb->rootdir = _rootdir_obj; processor_t *proc = processor_current(); - proc->pcb = s_init_pcb; proc->tss.rsp[0] = (uintptr_t)s_init_pcb->ksp; { jove_owned_obj_t *process_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PCB_I); obj_settype(process_obj, JOVE_OBJ_PROCESS); obj_setvalue(process_obj, (uintptr_t)s_init_pcb); - obj_release(process_obj); + + proc->pcb_obj = obj_release(process_obj); + proc->pcb = s_init_pcb; } __asm__ volatile("\ diff --git a/arch/x86_64/hal/process.h b/arch/x86_64/hal/process.h index 0c0fb5b..65b2318 100644 --- a/arch/x86_64/hal/process.h +++ b/arch/x86_64/hal/process.h @@ -1,22 +1,12 @@ #ifndef _JOVE_x86_64_HAL_PROCESS_H #define _JOVE_x86_64_HAL_PROCESS_H 1 -#include "hal/obj.h" +#include "hal/process.h" #include "arch/x86_64/x86_64.h" -enum pcb_state -{ - PCB_DEAD, PCB_READY, PCB_RUNNING, PCB_BLOCKED -}; - -struct pcb_mailbox -{ - jove_obj_t *obj; - uintmax_t pcbid; -}; - typedef struct process_control_block { + pid_t pid; jove_obj_t *rootdir; uintptr_t pml4; diff --git a/arch/x86_64/hal/smp.c b/arch/x86_64/hal/smp.c index e0945c1..85ba4ec 100644 --- a/arch/x86_64/hal/smp.c +++ b/arch/x86_64/hal/smp.c @@ -1,4 +1,5 @@ #include "smp.h" +#include "hal/process.h" #include "init.h" #include "hal/obj.h" #include "config.h" @@ -55,12 +56,7 @@ smp_init_bsp(void) } } -void *processor_current(void) +processor_t *processor_current(void) { return (processor_t*)msr_get_gs_base(); } - -jove_obj_t *processor_objdir(void *processor) -{ - return ((processor_t*)processor)->pcb->rootdir; -} diff --git a/arch/x86_64/hal/smp.h b/arch/x86_64/hal/smp.h index 68e420f..5813dd3 100644 --- a/arch/x86_64/hal/smp.h +++ b/arch/x86_64/hal/smp.h @@ -3,6 +3,7 @@ #include "gdt.h" #include "process.h" +#include "hal/obj.h" #include "hal/smp.h" typedef struct processor @@ -10,6 +11,7 @@ typedef struct processor struct gdt_entry gdt[GDT_TSS_HI+1]; struct tss tss; + jove_obj_t *pcb_obj; pcb_t *pcb; } processor_t; diff --git a/arch/x86_64/lib/elf.h b/arch/x86_64/lib/elf.h index fae2255..bd3e9cf 100644 --- a/arch/x86_64/lib/elf.h +++ b/arch/x86_64/lib/elf.h @@ -32,6 +32,8 @@ struct elf_header uint16_t e_shstrndx; }; +#define PT_LOAD 1 + struct elf_phdr { uint32_t p_type; diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c index 26eefde..cecca32 100644 --- a/arch/x86_64/sys/init.c +++ b/arch/x86_64/sys/init.c @@ -1,6 +1,7 @@ #include "init.h" #include "arch/x86_64/hal/msr.h" #include "config.h" +#include "hal/process.h" #include "jove.h" #include "hal/obj.h" #include "lib/string.h" @@ -98,15 +99,16 @@ init_setup(void) jove_owned_obj_t *init_pagedir = objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I); page_t *pml4 = obj_deref(init_pagedir); + size_t last_base = 0; //Load the init ELF - for(size_t i = 0; i < init_ehdr->e_shnum; i++) { - struct elf_shdr *shdr = init_data + init_ehdr->e_shoff + i * init_ehdr->e_shentsize; - if(shdr->sh_type != SHT_PROGBITS && shdr->sh_type != SHT_NOBITS) continue; - if((shdr->sh_flags & SHF_ALLOC) == 0) continue; + for(size_t i = 0; i < init_ehdr->e_phnum; i++) { + struct elf_phdr *phdr = init_data + init_ehdr->e_phoff + i * init_ehdr->e_phentsize; + if(phdr->p_type != PT_LOAD) continue; + kprintf("init: phdr %i flags %b\n", i, phdr->p_flags); - uintptr_t base = shdr->sh_addr; - size_t limit = shdr->sh_size; + uintptr_t base = phdr->p_vaddr; + size_t limit = phdr->p_memsz; uintptr_t page_base = base & ~0xFFFULL; size_t pml3i = (page_base >> PMLI_SHL(3)) & 0x1FF; @@ -125,15 +127,15 @@ init_setup(void) if(pml0i > INIT_PROGRAM_PAGES_MAX) { kpanic("init: Program exceeds maximum program pages in the same hugepage frame!\n"); } + if(last_base < base + limit) last_base = base + limit; uintptr_t pml0_pptr = init_program_pml0_pptr + (pml0i << 12); s_init_program_pml1[pml0i].value = pml0_pptr | PAGE_PRESENT | PAGE_USER | PAGE_WRITEABLE; } //Copy data from section if SHT_PROGBITS - if(shdr->sh_type == SHT_PROGBITS) { - memcpy((void*)shdr->sh_addr, init_data + shdr->sh_offset, shdr->sh_size); - } + kprintf("init: load %p : %p\n", base, limit); + memcpy((void*)phdr->p_vaddr, init_data + phdr->p_offset, phdr->p_memsz); } //Map the stack @@ -147,19 +149,37 @@ init_setup(void) s_init_stack_pml1[pml0i].value = page_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; } + //Map the syscall message. + last_base = (last_base + 0xFFF) & ~0xFFF; + size_t last_page = (last_base >> 12) & 0x1FF; + uintptr_t message_pptr = init_program_pml0_pptr + (last_page << 12); + s_init_program_pml1[last_page].value = message_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; + + jove_owned_obj_t *message_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_MESSAGE_I); + obj_settype(message_obj, JOVE_OBJ_MESSAGE); + obj_setvalue(message_obj, (message_pptr & ~0xFFF) | 1); + obj_release(message_obj); + obj_release(init_pagedir); //Enable syscalls extern void _syscall_entry(void); msr_set_lstar(_syscall_entry); + //Setup KSP for syscalls + jove_owned_obj_t *pcb_obj = process_current(); + pcb_t *pcb = obj_deref(pcb_obj); + + obj_release(pcb_obj); + uintptr_t usp = 0x00007FFFFFFFFFF8; uintptr_t uip = init_ehdr->e_entry; __asm__ volatile("movq %0, %%rsp; \ movq %1, %%rcx; \ + movq %2, %%rdi; \ movq $0x202, %%r11; \ swapgs; \ sysretq":: - "r"(usp), "r"(uip): "memory"); + "r"(usp), "r"(uip), "m"(last_base): "memory"); } diff --git a/arch/x86_64/sys/serial.c b/arch/x86_64/sys/serial.c new file mode 100644 index 0000000..48a14c7 --- /dev/null +++ b/arch/x86_64/sys/serial.c @@ -0,0 +1,41 @@ +#include "jove.h" +#include "lib/printf.h" +#include "syscall.h" +#include "arch/x86_64/hal/serial_com.h" + +static int +s_syscall_serial_write( + jove_owned_obj_t *serial_com, + size_t payload_bytes, + void *payload_data) +{ + if(payload_bytes < sizeof(struct syscall_serial_write)) { + kprintf("syscall_serial_write: message is too small for this syscall!\n"); + return EOOB; + } + struct syscall_serial_write *payload = payload_data; + if(payload_bytes < sizeof(struct syscall_serial_write) + payload->len) { + kprintf("syscall_serial_write: message is to small for payload!\n"); + return EOOB; + } + return serial_com_write(serial_com, payload->data, payload->len); +} + +int +_syscall_handle_serial( + jove_owned_obj_t *pcb_obj, + jove_owned_obj_t *objdir, + jove_owned_obj_t *message_obj, + jove_owned_obj_t *target_obj, + struct syscall_header *header, + size_t bytes_left, + void *payload_data) +{ + switch(header->callid) { + case 0: + return s_syscall_serial_write(target_obj, bytes_left, payload_data); + default: + kprintf("syscall_serial: serial com object does not support syscall %i\n", header->callid); + return EOOB; + } +} diff --git a/arch/x86_64/sys/syscall.c b/arch/x86_64/sys/syscall.c index 4e95225..b2d3e7f 100644 --- a/arch/x86_64/sys/syscall.c +++ b/arch/x86_64/sys/syscall.c @@ -1,24 +1,33 @@ +#include "arch/x86_64/hal/obj.h" #include "arch/x86_64/hal/process.h" #include "arch/x86_64/hal/smp.h" -#include "hal/smp.h" -#include "jove.h" +#include "lib/printf.h" + +#include "syscall.h" + +syscall_handle_t s_arch_handles[128] = { + [JOVE_OBJ_SERIAL_COM-0x80] = _syscall_handle_serial +}; int -syscall_handler_arch(uint64_t message_path_raw, uint64_t message_pathlen) +syscall_handle_arch( + jove_owned_obj_t *pcb_obj, + jove_owned_obj_t *objdir, + jove_owned_obj_t *message_obj, + jove_owned_obj_t *target_obj, + struct syscall_header *header, + size_t bytes_left, + void *payload) { - uint16_t *message_path = (uint16_t*)&message_path_raw; - if(message_pathlen > 4) { - return EBADPATH; - } - processor_t *proc = processor_current(); - jove_owned_obj_t *objdir = obj_take(proc->pcb->rootdir); - jove_owned_obj_t *message_obj = objdir_getobj(objdir, message_path, message_pathlen); - if(message_obj == 0) { - obj_release(objdir); - return errno; + uint8_t target_type = obj_gettype(target_obj) - 0x80; + syscall_handle_t call_handle = s_arch_handles[target_type]; + if(call_handle == NULL) { + kprintf("syscall: Process %i tried to call syscall on object %P which doesn't support syscalls!\n", + pcb_pid(obj_deref(pcb_obj)), header->path, header->pathlen); + return EBADOBJ; } - return 0; + return call_handle(pcb_obj, objdir, message_obj, target_obj, header, bytes_left, payload); } __attribute__((naked)) @@ -38,7 +47,7 @@ void _syscall_entry(void) pushq %%r13; \ pushq %%r14; \ pushq %%r15; \ - callq syscall_handler_arch; \ + callq syscall_handler; \ swapgs; \ popq %%r15; \ popq %%r14; \ @@ -53,7 +62,6 @@ void _syscall_entry(void) xorq %%r8, %%r8; \ xorq %%r9, %%r9; \ xorq %%r10, %%r10; \ - popq %%rcx; \ popq %%r11; \ popq %%rsp; \ sysretq;" diff --git a/arch/x86_64/sys/syscall.h b/arch/x86_64/sys/syscall.h new file mode 100644 index 0000000..1368897 --- /dev/null +++ b/arch/x86_64/sys/syscall.h @@ -0,0 +1,23 @@ +#ifndef _JOVE_ARCH_SYS_SYSCALL_H +#define _JOVE_ARCH_SYS_SYSCALL_H 1 + +#include "sys/syscall.h" + +int +_syscall_handle_serial( + jove_owned_obj_t *pcb_obj, + jove_owned_obj_t *objdir, + jove_owned_obj_t *message_obj, + jove_owned_obj_t *target_obj, + struct syscall_header *header, + size_t bytes_left, + void *payload); +struct syscall_serial_write +{ + size_t len; + char data[]; +}; + +#define SYSCALL_SERIAL_COM_WRITE 0 + +#endif |
