aboutsummaryrefslogtreecommitdiff
path: root/pk/pk.c
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-03-09 23:58:17 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-03-09 23:58:17 -0800
commitb94c7a4b07f96f24ae7411780abf874416549f7b (patch)
treeb94ca015e49392f52e5abf1209ee184fcf874db4 /pk/pk.c
parentf5a96732cb81571a3ba6b081b8556187d564f678 (diff)
downloadriscv-pk-b94c7a4b07f96f24ae7411780abf874416549f7b.zip
riscv-pk-b94c7a4b07f96f24ae7411780abf874416549f7b.tar.gz
riscv-pk-b94c7a4b07f96f24ae7411780abf874416549f7b.tar.bz2
Refactor pk, bbl, machine into separate libraries
Yuck.
Diffstat (limited to 'pk/pk.c')
-rw-r--r--pk/pk.c95
1 files changed, 82 insertions, 13 deletions
diff --git a/pk/pk.c b/pk/pk.c
index 6318963..2737048 100644
--- a/pk/pk.c
+++ b/pk/pk.c
@@ -1,24 +1,66 @@
#include "pk.h"
+#include "mmap.h"
#include "boot.h"
-#include "vm.h"
#include "elf.h"
+#include "mtrap.h"
+#include "frontend.h"
-void run_loaded_program(size_t argc, char** argv)
+elf_info current;
+
+int uarch_counters_enabled;
+long uarch_counters[NUM_COUNTERS];
+char* uarch_counter_names[NUM_COUNTERS];
+
+static void handle_option(const char* s)
{
- if (current.is_supervisor)
- panic("pk can't run kernel binaries; try using bbl instead");
+ switch (s[1])
+ {
+ case 's': // print cycle count upon termination
+ current.t0 = 1;
+ break;
- uintptr_t kernel_stack_top = pk_vm_init();
+ case 'c': // print uarch counters upon termination
+ // If your HW doesn't support uarch counters, then don't use this flag!
+ uarch_counters_enabled = 1;
+ break;
- extern char trap_entry;
- write_csr(stvec, &trap_entry);
- write_csr(sscratch, 0);
- clear_csr(sie, SIP_STIP | SIP_SSIP);
+ default:
+ panic("unrecognized option: `%c'", s[1]);
+ break;
+ }
+}
- // enter supervisor mode
- prepare_supervisor_mode();
- asm volatile("la t0, 1f; csrw mepc, t0; eret; 1:" ::: "t0");
+#define MAX_ARGS 64
+typedef union {
+ uint64_t buf[MAX_ARGS];
+ char* argv[MAX_ARGS];
+} arg_buf;
+
+static size_t parse_args(arg_buf* args)
+{
+ long r = frontend_syscall(SYS_getmainvars, (uintptr_t)args, sizeof(*args), 0, 0, 0, 0, 0);
+ kassert(r == 0);
+ uint64_t* pk_argv = &args->buf[1];
+ // pk_argv[0] is the proxy kernel itself. skip it and any flags.
+ size_t pk_argc = args->buf[0], arg = 1;
+ for ( ; arg < pk_argc && *(char*)(uintptr_t)pk_argv[arg] == '-'; arg++)
+ handle_option((const char*)(uintptr_t)pk_argv[arg]);
+
+ for (size_t i = 0; arg + i < pk_argc; i++)
+ args->argv[i] = (char*)(uintptr_t)pk_argv[arg + i];
+ return pk_argc - arg;
+}
+
+static void init_tf(trapframe_t* tf, long pc, long sp)
+{
+ memset(tf, 0, sizeof(*tf));
+ tf->status = (read_csr(sstatus) &~ SSTATUS_SPP &~ SSTATUS_SIE) | SSTATUS_SPIE;
+ tf->gpr[2] = sp;
+ tf->epc = pc;
+}
+static void run_loaded_program(size_t argc, char** argv, uintptr_t kstack_top)
+{
// 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);
@@ -94,10 +136,37 @@ void run_loaded_program(size_t argc, char** argv)
trapframe_t tf;
init_tf(&tf, current.entry, stack_top);
__clear_cache(0, 0);
- write_csr(sscratch, kernel_stack_top);
+ write_csr(sscratch, kstack_top);
start_user(&tf);
}
+static void rest_of_boot_loader(uintptr_t kstack_top)
+{
+ arg_buf args;
+ size_t argc = parse_args(&args);
+ if (!argc)
+ panic("tell me what ELF to load!");
+
+ // load program named by argv[0]
+ long phdrs[128];
+ current.phdr = (uintptr_t)phdrs;
+ current.phdr_size = sizeof(phdrs);
+ load_elf(args.argv[0], &current);
+
+ run_loaded_program(argc, args.argv, kstack_top);
+}
+
+void boot_loader()
+{
+ extern char trap_entry;
+ write_csr(stvec, &trap_entry);
+ write_csr(sscratch, 0);
+ write_csr(sie, 0);
+
+ file_init();
+ enter_supervisor_mode(rest_of_boot_loader, pk_vm_init());
+}
+
void boot_other_hart()
{
// stall all harts besides hart 0