From 87683e74f566afe6acaf77fd79cc0bf2746bf136 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 10 May 2015 22:16:46 -0700 Subject: Split pk functionality into pk and bbl pk is now an AEE only (i.e. it can only execute user programs). bbl is now an SEE only (i.e. it can only host kernels). --- pk/bbl.c | 16 ++++++++++ pk/console.c | 4 +-- pk/frontend.c | 7 +++++ pk/frontend.h | 1 + pk/init.c | 96 ++------------------------------------------------------- pk/pk.S | 0 pk/pk.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pk/pk.h | 3 +- pk/pk.mk.in | 3 +- pk/syscall.c | 3 +- pk/syscall.h | 1 - pk/vm.c | 4 --- 12 files changed, 132 insertions(+), 105 deletions(-) create mode 100644 pk/bbl.c delete mode 100644 pk/pk.S create mode 100644 pk/pk.c (limited to 'pk') 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 #include #include @@ -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 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); diff --git a/pk/init.c b/pk/init.c index 683c366..851e878 100644 --- a/pk/init.c +++ b/pk/init.c @@ -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 diff --git a/pk/pk.c b/pk/pk.c new file mode 100644 index 0000000..cc2a761 --- /dev/null +++ b/pk/pk.c @@ -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); +} diff --git a/pk/pk.h b/pk/pk.h index 5b9f3dd..ee449aa 100644 --- a/pk/pk.h +++ b/pk/pk.h @@ -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 diff --git a/pk/vm.c b/pk/vm.c index 50d3c16..e9c20bd 100644 --- a/pk/vm.c +++ b/pk/vm.c @@ -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; -- cgit v1.1