aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-05-10 22:16:46 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-05-10 22:17:39 -0700
commit87683e74f566afe6acaf77fd79cc0bf2746bf136 (patch)
treee1ced1ee44c10ec1662897abde09e4bed2d0dcca
parent50a2d6ca7fb63cfabd0f8bc086abb8fcd49f0ded (diff)
downloadriscv-pk-87683e74f566afe6acaf77fd79cc0bf2746bf136.zip
riscv-pk-87683e74f566afe6acaf77fd79cc0bf2746bf136.tar.gz
riscv-pk-87683e74f566afe6acaf77fd79cc0bf2746bf136.tar.bz2
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).
-rw-r--r--Makefile.in12
-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
13 files changed, 138 insertions, 111 deletions
diff --git a/Makefile.in b/Makefile.in
index 0ab3e6c..a6c22d8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -232,14 +232,14 @@ $(2)_junk += $$($(2)_test_outs)
# Build programs
-$(2)_prog_objs := $$(patsubst %.S, %.o, $$($(2)_prog_srcs))
+$(2)_prog_objs := $$(patsubst %.c, %.o, $$($(2)_prog_srcs))
$(2)_prog_deps := $$(patsubst %.o, %.d, $$($(2)_prog_objs))
-$(2)_prog_exes := $$(patsubst %.S, %, $$($(2)_prog_srcs))
+$(2)_prog_exes := $$(patsubst %.c, %, $$($(2)_prog_srcs))
$(2)_prog_libs := $(1) $$($(2)_reverse_deps)
$(2)_prog_libnames := $$(patsubst %, lib%.a, $$($(2)_prog_libs))
$(2)_prog_libarg := -L. $$(patsubst %, -l%, $$($(2)_prog_libs))
-$$($(2)_prog_objs) : %.o : %.S
+$$($(2)_prog_objs) : %.o : %.c
$(COMPILE) -c $$<
$$($(2)_prog_exes) : % : %.o $$($(2)_prog_libnames)
@@ -250,11 +250,11 @@ $(2)_junk += $$($(2)_prog_objs) $$($(2)_prog_deps) $$($(2)_prog_exes)
# Build programs which will be installed
-$(2)_install_prog_objs := $$(patsubst %.S, %.o, $$($(2)_install_prog_srcs))
+$(2)_install_prog_objs := $$(patsubst %.c, %.o, $$($(2)_install_prog_srcs))
$(2)_install_prog_deps := $$(patsubst %.o, %.d, $$($(2)_install_prog_objs))
-$(2)_install_prog_exes := $$(patsubst %.S, %, $$($(2)_install_prog_srcs))
+$(2)_install_prog_exes := $$(patsubst %.c, %, $$($(2)_install_prog_srcs))
-$$($(2)_install_prog_objs) : %.o : %.S
+$$($(2)_install_prog_objs) : %.o : %.c
$(COMPILE) -c $$<
$$($(2)_install_prog_exes) : % : %.o $$($(2)_prog_libnames)
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;