aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
Diffstat (limited to 'pk')
-rw-r--r--pk/bbl.c16
-rw-r--r--pk/console.c4
-rw-r--r--pk/frontend.c7
-rw-r--r--pk/frontend.h1
-rw-r--r--pk/init.c96
-rw-r--r--pk/pk.S0
-rw-r--r--pk/pk.c99
-rw-r--r--pk/pk.h3
-rw-r--r--pk/pk.mk.in3
-rw-r--r--pk/syscall.c3
-rw-r--r--pk/syscall.h1
-rw-r--r--pk/vm.c4
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);
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], &current);
- 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
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;