diff options
Diffstat (limited to 'pk')
-rw-r--r-- | pk/bbl.c | 16 | ||||
-rw-r--r-- | pk/console.c | 4 | ||||
-rw-r--r-- | pk/frontend.c | 7 | ||||
-rw-r--r-- | pk/frontend.h | 1 | ||||
-rw-r--r-- | pk/init.c | 96 | ||||
-rw-r--r-- | pk/pk.S | 0 | ||||
-rw-r--r-- | pk/pk.c | 99 | ||||
-rw-r--r-- | pk/pk.h | 3 | ||||
-rw-r--r-- | pk/pk.mk.in | 3 | ||||
-rw-r--r-- | pk/syscall.c | 3 | ||||
-rw-r--r-- | pk/syscall.h | 1 | ||||
-rw-r--r-- | pk/vm.c | 4 |
12 files changed, 132 insertions, 105 deletions
diff --git a/pk/bbl.c b/pk/bbl.c new file mode 100644 index 0000000..f4f0f06 --- /dev/null +++ b/pk/bbl.c @@ -0,0 +1,16 @@ +#include "pk.h" +#include "vm.h" + +void run_loaded_program(struct mainvars* args) +{ + if (!current.is_supervisor) + panic("bbl can't run user binaries; try using pk instead"); + + supervisor_vm_init(); +#ifdef PK_ENABLE_LOGO + print_logo(); +#endif + write_csr(mepc, current.entry); + asm volatile("eret"); + __builtin_unreachable(); +} diff --git a/pk/console.c b/pk/console.c index 69bb9e9..3920a51 100644 --- a/pk/console.c +++ b/pk/console.c @@ -1,6 +1,6 @@ #include "pk.h" #include "file.h" -#include "syscall.h" +#include "frontend.h" #include <stdint.h> #include <stdarg.h> #include <stdbool.h> @@ -138,7 +138,7 @@ void do_panic(const char* s, ...) va_start(vl, s); vprintk(s, vl); - sys_exit(-1); + die(-1); va_end(vl); } diff --git a/pk/frontend.c b/pk/frontend.c index 0929d54..52e26fa 100644 --- a/pk/frontend.c +++ b/pk/frontend.c @@ -5,6 +5,7 @@ #include "frontend.h" #include "sbi.h" #include "mcall.h" +#include "syscall.h" #include <stdint.h> uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload) @@ -44,3 +45,9 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long spinlock_unlock(&lock); return ret; } + +void die(int code) +{ + frontend_syscall(SYS_exit, code, 0, 0, 0, 0, 0, 0); + while (1); +} diff --git a/pk/frontend.h b/pk/frontend.h index b6418f2..40f7c19 100644 --- a/pk/frontend.h +++ b/pk/frontend.h @@ -17,6 +17,7 @@ #define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56) #define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16) +void die(int) __attribute__((noreturn)); long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long a5, long a6); uint64_t tohost_sync(unsigned dev, unsigned cmd, uint64_t payload); @@ -84,7 +84,7 @@ struct mainvars* parse_args(struct mainvars* args) return (struct mainvars*)&args->argv[a0-1]; } -uintptr_t boot_loader(struct mainvars* args) +void boot_loader(struct mainvars* args) { // load program named by argv[0] long phdrs[128]; @@ -94,97 +94,5 @@ uintptr_t boot_loader(struct mainvars* args) panic("tell me what ELF to load!"); load_elf((char*)(uintptr_t)args->argv[0], ¤t); - if (current.is_supervisor) { - supervisor_vm_init(); -#ifdef PK_ENABLE_LOGO - print_logo(); -#endif - write_csr(mepc, current.entry); - asm volatile("eret"); - __builtin_unreachable(); - } - - uintptr_t kernel_stack_top = pk_vm_init(); - asm volatile("la t0, 1f; csrw mepc, t0; eret; 1:" ::: "t0"); - - // copy phdrs to user stack - size_t stack_top = current.stack_top - current.phdr_size; - memcpy((void*)stack_top, (void*)current.phdr, current.phdr_size); - current.phdr = stack_top; - - // copy argv to user stack - for (size_t i = 0; i < args->argc; i++) { - size_t len = strlen((char*)(uintptr_t)args->argv[i])+1; - stack_top -= len; - memcpy((void*)stack_top, (void*)(uintptr_t)args->argv[i], len); - args->argv[i] = stack_top; - } - stack_top &= -sizeof(void*); - - struct { - long key; - long value; - } aux[] = { - {AT_ENTRY, current.entry}, - {AT_PHNUM, current.phnum}, - {AT_PHENT, current.phent}, - {AT_PHDR, current.phdr}, - {AT_PAGESZ, RISCV_PGSIZE}, - {AT_SECURE, 0}, - {AT_RANDOM, stack_top}, - {AT_NULL, 0} - }; - - // place argc, argv, envp, auxp on stack - #define PUSH_ARG(type, value) do { \ - *((type*)sp) = value; \ - sp += sizeof(type); \ - } while (0) - - #define STACK_INIT(type) do { \ - unsigned naux = sizeof(aux)/sizeof(aux[0]); \ - stack_top -= (1 + args->argc + 1 + 1 + 2*naux) * sizeof(type); \ - stack_top &= -16; \ - long sp = stack_top; \ - PUSH_ARG(type, args->argc); \ - for (unsigned i = 0; i < args->argc; i++) \ - PUSH_ARG(type, args->argv[i]); \ - PUSH_ARG(type, 0); /* argv[argc] = NULL */ \ - PUSH_ARG(type, 0); /* envp[0] = NULL */ \ - for (unsigned i = 0; i < naux; i++) { \ - PUSH_ARG(type, aux[i].key); \ - PUSH_ARG(type, aux[i].value); \ - } \ - } while (0) - - if (current.elf64) - STACK_INIT(uint64_t); - else - STACK_INIT(uint32_t); - - if (current.t0) // start timer if so requested - current.t0 = rdcycle(); - - if (uarch_counters_enabled) { // start tracking the uarch counters if requested - size_t i = 0; - #define READ_CTR_INIT(name) do { \ - while (i >= NUM_COUNTERS) ; \ - long csr = read_csr(name); \ - uarch_counters[i++] = csr; \ - } while (0) - READ_CTR_INIT(cycle); READ_CTR_INIT(instret); - READ_CTR_INIT(uarch0); READ_CTR_INIT(uarch1); READ_CTR_INIT(uarch2); - READ_CTR_INIT(uarch3); READ_CTR_INIT(uarch4); READ_CTR_INIT(uarch5); - READ_CTR_INIT(uarch6); READ_CTR_INIT(uarch7); READ_CTR_INIT(uarch8); - READ_CTR_INIT(uarch9); READ_CTR_INIT(uarch10); READ_CTR_INIT(uarch11); - READ_CTR_INIT(uarch12); READ_CTR_INIT(uarch13); READ_CTR_INIT(uarch14); - READ_CTR_INIT(uarch15); - #undef READ_CTR_INIT - } - - trapframe_t tf; - init_tf(&tf, current.entry, stack_top, current.elf64); - __clear_cache(0, 0); - write_csr(sscratch, kernel_stack_top); - start_user(&tf); + run_loaded_program(args); } diff --git a/pk/pk.S b/pk/pk.S deleted file mode 100644 index e69de29..0000000 --- a/pk/pk.S +++ /dev/null @@ -0,0 +1,99 @@ +#include "pk.h" +#include "vm.h" +#include "elf.h" + +void run_loaded_program(struct mainvars* args) +{ + if (current.is_supervisor) + panic("pk can't run kernel binaries; try using bbl instead"); + + uintptr_t kernel_stack_top = pk_vm_init(); + + extern char trap_entry; + write_csr(stvec, &trap_entry); + write_csr(sscratch, 0); + + // enter supervisor mode + asm volatile("la t0, 1f; csrw mepc, t0; eret; 1:" ::: "t0"); + + // copy phdrs to user stack + size_t stack_top = current.stack_top - current.phdr_size; + memcpy((void*)stack_top, (void*)current.phdr, current.phdr_size); + current.phdr = stack_top; + + // copy argv to user stack + for (size_t i = 0; i < args->argc; i++) { + size_t len = strlen((char*)(uintptr_t)args->argv[i])+1; + stack_top -= len; + memcpy((void*)stack_top, (void*)(uintptr_t)args->argv[i], len); + args->argv[i] = stack_top; + } + stack_top &= -sizeof(void*); + + struct { + long key; + long value; + } aux[] = { + {AT_ENTRY, current.entry}, + {AT_PHNUM, current.phnum}, + {AT_PHENT, current.phent}, + {AT_PHDR, current.phdr}, + {AT_PAGESZ, RISCV_PGSIZE}, + {AT_SECURE, 0}, + {AT_RANDOM, stack_top}, + {AT_NULL, 0} + }; + + // place argc, argv, envp, auxp on stack + #define PUSH_ARG(type, value) do { \ + *((type*)sp) = value; \ + sp += sizeof(type); \ + } while (0) + + #define STACK_INIT(type) do { \ + unsigned naux = sizeof(aux)/sizeof(aux[0]); \ + stack_top -= (1 + args->argc + 1 + 1 + 2*naux) * sizeof(type); \ + stack_top &= -16; \ + long sp = stack_top; \ + PUSH_ARG(type, args->argc); \ + for (unsigned i = 0; i < args->argc; i++) \ + PUSH_ARG(type, args->argv[i]); \ + PUSH_ARG(type, 0); /* argv[argc] = NULL */ \ + PUSH_ARG(type, 0); /* envp[0] = NULL */ \ + for (unsigned i = 0; i < naux; i++) { \ + PUSH_ARG(type, aux[i].key); \ + PUSH_ARG(type, aux[i].value); \ + } \ + } while (0) + + if (current.elf64) + STACK_INIT(uint64_t); + else + STACK_INIT(uint32_t); + + if (current.t0) // start timer if so requested + current.t0 = rdcycle(); + + if (uarch_counters_enabled) { // start tracking the uarch counters if requested + size_t i = 0; + #define READ_CTR_INIT(name) do { \ + while (i >= NUM_COUNTERS) ; \ + long csr = read_csr(name); \ + uarch_counters[i++] = csr; \ + } while (0) + READ_CTR_INIT(cycle); READ_CTR_INIT(instret); + READ_CTR_INIT(uarch0); READ_CTR_INIT(uarch1); READ_CTR_INIT(uarch2); + READ_CTR_INIT(uarch3); READ_CTR_INIT(uarch4); READ_CTR_INIT(uarch5); + READ_CTR_INIT(uarch6); READ_CTR_INIT(uarch7); READ_CTR_INIT(uarch8); + READ_CTR_INIT(uarch9); READ_CTR_INIT(uarch10); READ_CTR_INIT(uarch11); + READ_CTR_INIT(uarch12); READ_CTR_INIT(uarch13); READ_CTR_INIT(uarch14); + READ_CTR_INIT(uarch15); + #undef READ_CTR_INIT + } + + trapframe_t tf; + init_tf(&tf, current.entry, stack_top, current.elf64); + __clear_cache(0, 0); + write_csr(sscratch, kernel_stack_top); + start_user(&tf); +} @@ -59,7 +59,8 @@ void handle_misaligned_load(trapframe_t*); void handle_misaligned_store(trapframe_t*); void handle_fault_load(trapframe_t*); void handle_fault_store(trapframe_t*); -uintptr_t boot_loader(struct mainvars*); +void boot_loader(struct mainvars*); +void run_loaded_program(struct mainvars*); typedef struct { int elf64; diff --git a/pk/pk.mk.in b/pk/pk.mk.in index 3c0b455..4772556 100644 --- a/pk/pk.mk.in +++ b/pk/pk.mk.in @@ -36,4 +36,5 @@ pk_asm_srcs = \ pk_test_srcs = pk_install_prog_srcs = \ - pk.S \ + pk.c \ + bbl.c \ diff --git a/pk/syscall.c b/pk/syscall.c index 2e14d22..44c62cd 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -50,8 +50,7 @@ void sys_exit(int code) } } - frontend_syscall(SYS_exit, code, 0, 0, 0, 0, 0, 0); - while (1); + die(code); } ssize_t sys_read(int fd, char* buf, size_t n) diff --git a/pk/syscall.h b/pk/syscall.h index 98441f0..a4a1522 100644 --- a/pk/syscall.h +++ b/pk/syscall.h @@ -60,7 +60,6 @@ #define AT_FDCWD -100 -void sys_exit(int code) __attribute__((noreturn)); long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, unsigned long n); #endif @@ -497,10 +497,6 @@ uintptr_t pk_vm_init() __map_kernel_range(0, 0, current.first_free_paddr, PROT_READ|PROT_WRITE|PROT_EXEC); __map_kernel_range(first_free_page, first_free_page, free_pages * RISCV_PGSIZE, PROT_READ|PROT_WRITE); - extern char trap_entry; - write_csr(stvec, &trap_entry); - write_csr(sscratch, 0); - size_t stack_size = RISCV_PGSIZE * CLAMP(mem_size/(RISCV_PGSIZE*32), 1, 256); current.stack_bottom = __do_mmap(current.mmap_max - stack_size, stack_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0); current.stack_top = current.stack_bottom + stack_size; |