aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-03-05 14:34:18 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-03-05 14:34:18 -0800
commit80447e5711461fa58cf61d17a6a1b79f7dcd5294 (patch)
tree56a5ace30a808a606346c63b9d533cbcb787619e /pk
parentbbc9a65fed7c85ee058d7188a62f0b904c38b77b (diff)
downloadriscv-pk-80447e5711461fa58cf61d17a6a1b79f7dcd5294.zip
riscv-pk-80447e5711461fa58cf61d17a6a1b79f7dcd5294.tar.gz
riscv-pk-80447e5711461fa58cf61d17a6a1b79f7dcd5294.tar.bz2
Disentangle PK and BBL a bit
Diffstat (limited to 'pk')
-rw-r--r--pk/bbl.c5
-rw-r--r--pk/bits.h6
-rw-r--r--pk/boot.h47
-rw-r--r--pk/configstring.c11
-rw-r--r--pk/console.c96
-rw-r--r--pk/elf.c9
-rw-r--r--pk/emulation.c2
-rw-r--r--pk/frontend.c2
-rw-r--r--pk/frontend.h2
-rw-r--r--pk/init.c8
-rw-r--r--pk/minit.c40
-rw-r--r--pk/mtrap.c28
-rw-r--r--pk/mtrap.h18
-rw-r--r--pk/pk.c1
-rw-r--r--pk/pk.h52
-rw-r--r--pk/pk.mk.in2
-rw-r--r--pk/sbi_impl.c7
-rw-r--r--pk/snprintf.c98
-rw-r--r--pk/syscall.c3
-rw-r--r--pk/vm.c2
-rw-r--r--pk/vm.h5
21 files changed, 226 insertions, 218 deletions
diff --git a/pk/bbl.c b/pk/bbl.c
index dc6e1ea..031fa08 100644
--- a/pk/bbl.c
+++ b/pk/bbl.c
@@ -1,4 +1,5 @@
-#include "pk.h"
+#include "boot.h"
+#include "mtrap.h"
#include "vm.h"
#include "config.h"
@@ -15,7 +16,7 @@ static void enter_entry_point()
void run_loaded_program(struct mainvars* args)
{
if (!current.is_supervisor)
- panic("bbl can't run user binaries; try using pk instead");
+ die("bbl can't run user binaries; try using pk instead");
supervisor_vm_init();
#ifdef PK_ENABLE_LOGO
diff --git a/pk/bits.h b/pk/bits.h
index 9947351..10f9df3 100644
--- a/pk/bits.h
+++ b/pk/bits.h
@@ -4,6 +4,12 @@
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
+#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
+#define ROUNDDOWN(a, b) ((a)/(b)*(b))
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
#define CONST_POPCOUNT2(x) ((((x) >> 0) & 1) + (((x) >> 1) & 1))
#define CONST_POPCOUNT4(x) (CONST_POPCOUNT2(x) + CONST_POPCOUNT2((x)>>2))
#define CONST_POPCOUNT8(x) (CONST_POPCOUNT4(x) + CONST_POPCOUNT4((x)>>4))
diff --git a/pk/boot.h b/pk/boot.h
new file mode 100644
index 0000000..d0d97d6
--- /dev/null
+++ b/pk/boot.h
@@ -0,0 +1,47 @@
+// See LICENSE for license details.
+
+#ifndef _BOOT_H
+#define _BOOT_H
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct mainvars {
+ uint64_t argc;
+ uint64_t argv[127]; // this space is shared with the arg strings themselves
+};
+
+typedef struct {
+ int phent;
+ int phnum;
+ int is_supervisor;
+ size_t phdr;
+ size_t phdr_size;
+ size_t first_free_paddr;
+ size_t first_user_vaddr;
+ size_t first_vaddr_after_user;
+ size_t bias;
+ size_t entry;
+ size_t brk_min;
+ size_t brk;
+ size_t brk_max;
+ size_t mmap_max;
+ size_t stack_bottom;
+ size_t stack_top;
+ size_t t0;
+} elf_info;
+
+extern elf_info current;
+
+void prepare_supervisor_mode();
+void run_loaded_program(struct mainvars*);
+void boot_loader();
+void boot_other_hart();
+void load_elf(const char* fn, elf_info* info);
+void print_logo();
+
+#endif // !__ASSEMBLER__
+
+#endif
diff --git a/pk/configstring.c b/pk/configstring.c
index 288d211..847cd4d 100644
--- a/pk/configstring.c
+++ b/pk/configstring.c
@@ -1,5 +1,6 @@
#include "encoding.h"
#include "mtrap.h"
+#include <stdio.h>
static const char* skip_whitespace(const char* str)
{
@@ -163,11 +164,10 @@ static long get_sint(query_result res)
static void query_mem(const char* config_string)
{
query_result res = query_config_string(config_string, "ram{0{addr");
- kassert(res.start);
+ assert(res.start);
uintptr_t base = get_uint(res);
res = query_config_string(config_string, "ram{0{size");
mem_size = get_uint(res);
- debug_printk("at %p, found %d MiB of memory\n", base, (int)(mem_size >> 20));
}
static void query_harts(const char* config_string)
@@ -182,18 +182,19 @@ static void query_harts(const char* config_string)
csr_t* base = (csr_t*)get_uint(res);
uintptr_t hart_id = base[CSR_MHARTID];
hls_init(hart_id, base);
- debug_printk("at %p, found hart %ld\n", base, hart_id);
- kassert(num_harts++ == hart_id);
+ num_harts++;
+ assert(hart_id == num_harts-1);
}
if (!hart)
break;
}
+ assert(num_harts);
+ assert(num_harts <= MAX_HARTS);
}
void parse_config_string()
{
const char* s = (const char*)read_csr(mcfgaddr);
- debug_printk("%s\n", s);
query_mem(s);
query_harts(s);
}
diff --git a/pk/console.c b/pk/console.c
index 097842b..de7f0a8 100644
--- a/pk/console.c
+++ b/pk/console.c
@@ -3,91 +3,6 @@
#include "frontend.h"
#include <stdint.h>
#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-
-int vsnprintf(char* out, size_t n, const char* s, va_list vl)
-{
- bool format = false;
- bool longarg = false;
- size_t pos = 0;
- for( ; *s; s++)
- {
- if(format)
- {
- switch(*s)
- {
- case 'l':
- longarg = true;
- break;
- case 'p':
- longarg = true;
- if (++pos < n) out[pos-1] = '0';
- if (++pos < n) out[pos-1] = 'x';
- case 'x':
- {
- long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
- for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--) {
- int d = (num >> (4*i)) & 0xF;
- if (++pos < n) out[pos-1] = (d < 10 ? '0'+d : 'a'+d-10);
- }
- longarg = false;
- format = false;
- break;
- }
- case 'd':
- {
- long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
- if (num < 0) {
- num = -num;
- if (++pos < n) out[pos-1] = '-';
- }
- long digits = 1;
- for (long nn = num; nn /= 10; digits++)
- ;
- for (int i = digits-1; i >= 0; i--) {
- if (pos + i + 1 < n) out[pos + i] = '0' + (num % 10);
- num /= 10;
- }
- pos += digits;
- longarg = false;
- format = false;
- break;
- }
- case 's':
- {
- const char* s2 = va_arg(vl, const char*);
- while (*s2) {
- if (++pos < n)
- out[pos-1] = *s2;
- s2++;
- }
- longarg = false;
- format = false;
- break;
- }
- case 'c':
- {
- if (++pos < n) out[pos-1] = (char)va_arg(vl,int);
- longarg = false;
- format = false;
- break;
- }
- default:
- panic("bad fmt");
- }
- }
- else if(*s == '%')
- format = true;
- else
- if (++pos < n) out[pos-1] = *s;
- }
- if (pos < n)
- out[pos] = 0;
- else if (n)
- out[n-1] = 0;
- return pos;
-}
static void vprintk(const char* s, va_list vl)
{
@@ -106,15 +21,6 @@ void printk(const char* s, ...)
va_end(vl);
}
-int snprintf(char* out, size_t n, const char* s, ...)
-{
- va_list vl;
- va_start(vl, s);
- int res = vsnprintf(out, n, s, vl);
- va_end(vl);
- return res;
-}
-
void dump_tf(trapframe_t* tf)
{
static const char* regnames[] = {
@@ -141,7 +47,7 @@ void do_panic(const char* s, ...)
va_start(vl, s);
vprintk(s, vl);
- die(-1);
+ shutdown(-1);
va_end(vl);
}
diff --git a/pk/elf.c b/pk/elf.c
index 5f7210c..7dc783a 100644
--- a/pk/elf.c
+++ b/pk/elf.c
@@ -1,8 +1,9 @@
// See LICENSE for license details.
#include "file.h"
-#include "pk.h"
#include "vm.h"
+#include "mtrap.h"
+#include "boot.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>
@@ -87,7 +88,7 @@ void load_elf(const char* fn, elf_info* info)
if (IS_ELF64(eh64))
{
#ifndef __riscv64
- panic("can't run 64-bit ELF on 32-bit arch");
+ die("can't run 64-bit ELF on 32-bit arch");
#endif
Elf64_Ehdr* eh;
Elf64_Phdr* ph;
@@ -96,7 +97,7 @@ void load_elf(const char* fn, elf_info* info)
else if (IS_ELF32(eh64))
{
#ifdef __riscv64
- panic("can't run 32-bit ELF on 64-bit arch");
+ die("can't run 32-bit ELF on 64-bit arch");
#endif
Elf32_Ehdr* eh;
Elf32_Phdr* ph;
@@ -113,5 +114,5 @@ void load_elf(const char* fn, elf_info* info)
return;
fail:
- panic("couldn't open ELF program: %s!", fn);
+ die("couldn't open ELF program: %s!", fn);
}
diff --git a/pk/emulation.c b/pk/emulation.c
index 4943e0d..c454962 100644
--- a/pk/emulation.c
+++ b/pk/emulation.c
@@ -151,7 +151,7 @@ void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
return truly_illegal_insn(regs, mcause, mepc, mstatus, insn);
uintptr_t addr = GET_RS1(insn, regs) + IMM_S(insn);
- for (size_t i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
store_uint8_t((void *)(addr + i), val.bytes[i], mepc);
write_csr(mepc, mepc + 4);
diff --git a/pk/frontend.c b/pk/frontend.c
index 5055a28..f0e629f 100644
--- a/pk/frontend.c
+++ b/pk/frontend.c
@@ -32,7 +32,7 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long
return ret;
}
-void die(int code)
+void shutdown(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 ea5d244..2cf5f81 100644
--- a/pk/frontend.h
+++ b/pk/frontend.h
@@ -18,7 +18,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));
+void shutdown(int) __attribute__((noreturn));
long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4, long a5, long a6);
struct frontend_stat {
diff --git a/pk/init.c b/pk/init.c
index 57f5fca..6a459f9 100644
--- a/pk/init.c
+++ b/pk/init.c
@@ -1,6 +1,7 @@
// See LICENSE for license details.
#include "pk.h"
+#include "boot.h"
#include "file.h"
#include "vm.h"
#include "frontend.h"
@@ -43,7 +44,7 @@ static void handle_option(const char* s)
}
}
-struct mainvars* parse_args(struct mainvars* args)
+static struct mainvars* parse_args(struct mainvars* args)
{
long r = frontend_syscall(SYS_getmainvars, (uintptr_t)args, sizeof(*args), 0, 0, 0, 0, 0);
kassert(r == 0);
@@ -56,8 +57,11 @@ struct mainvars* parse_args(struct mainvars* args)
return (struct mainvars*)&args->argv[a0-1];
}
-void boot_loader(struct mainvars* args)
+void boot_loader()
{
+ struct mainvars arg_buffer;
+ struct mainvars *args = parse_args(&arg_buffer);
+
// load program named by argv[0]
long phdrs[128];
current.phdr = (uintptr_t)phdrs;
diff --git a/pk/minit.c b/pk/minit.c
index 42cdfe8..ad9598b 100644
--- a/pk/minit.c
+++ b/pk/minit.c
@@ -1,23 +1,20 @@
#include "vm.h"
#include "mtrap.h"
#include "fp_emulation.h"
+#include "boot.h"
uintptr_t mem_size;
uint32_t num_harts;
static void mstatus_init()
{
- if (!supports_extension('S'))
- panic("supervisor support is required");
-
uintptr_t ms = 0;
ms = INSERT_FIELD(ms, MSTATUS_VM, VM_CHOICE);
ms = INSERT_FIELD(ms, MSTATUS_FS, 1);
write_csr(mstatus, ms);
- ms = read_csr(mstatus);
- if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE)
- have_vm = 0;
+ ms = read_csr(mstatus);
+ assert(EXTRACT_FIELD(ms, MSTATUS_VM) == VM_CHOICE);
write_csr(mtimecmp, 0);
clear_csr(mip, MIP_MSIP);
@@ -40,35 +37,23 @@ static void delegate_traps()
write_csr(mideleg, interrupts);
write_csr(medeleg, exceptions);
- kassert(read_csr(mideleg) == interrupts);
- kassert(read_csr(medeleg) == exceptions);
-}
-
-static void memory_init()
-{
- if (mem_size == 0)
- panic("could not determine memory capacity");
-
- if ((intptr_t)mem_size < 0)
- mem_size = INTPTR_MIN;
-
- if (num_harts == 0)
- panic("could not determine number of harts");
+ assert(read_csr(mideleg) == interrupts);
+ assert(read_csr(medeleg) == exceptions);
}
static void fp_init()
{
- kassert(read_csr(mstatus) & MSTATUS_FS);
+ assert(read_csr(mstatus) & MSTATUS_FS);
#ifdef __riscv_hard_float
if (!supports_extension('D'))
- panic("FPU not found; recompile pk with -msoft-float");
+ die("FPU not found; recompile pk with -msoft-float");
for (int i = 0; i < 32; i++)
init_fp_reg(i);
write_csr(fcsr, 0);
#else
if (supports_extension('D'))
- panic("FPU unexpectedly found; recompile pk without -msoft-float");
+ die("FPU unexpectedly found; recompile with -mhard-float");
#endif
}
@@ -93,13 +78,8 @@ void init_first_hart()
memset(HLS(), 0, sizeof(*HLS()));
parse_config_string();
-
- struct mainvars arg_buffer;
- struct mainvars *args = parse_args(&arg_buffer);
-
- memory_init();
vm_init();
- boot_loader(args);
+ boot_loader();
}
void init_other_hart()
@@ -113,7 +93,7 @@ void init_other_hart()
write_csr(sptbr, (uintptr_t)root_page_table >> RISCV_PGSHIFT);
// make sure hart 0 has discovered us
- kassert(HLS()->csrs != NULL);
+ assert(HLS()->csrs != NULL);
boot_other_hart();
}
diff --git a/pk/mtrap.c b/pk/mtrap.c
index 52b85d8..b64360e 100644
--- a/pk/mtrap.c
+++ b/pk/mtrap.c
@@ -3,10 +3,12 @@
#include "mcall.h"
#include "vm.h"
#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
void __attribute__((noreturn)) bad_trap()
{
- panic("machine mode: unhandlable trap %d @ %p", read_csr(mcause), read_csr(mepc));
+ die("machine mode: unhandlable trap %d @ %p", read_csr(mcause), read_csr(mepc));
}
static uintptr_t mcall_hart_id()
@@ -17,14 +19,15 @@ static uintptr_t mcall_hart_id()
static void request_htif_keyboard_interrupt()
{
uintptr_t old_tohost = swap_csr(mtohost, TOHOST_CMD(1, 0, 0));
- kassert(old_tohost == 0);
+ assert(old_tohost == 0);
}
void htif_interrupt()
{
- // we should only be interrupted by keypresses
uintptr_t fromhost = swap_csr(mfromhost, 0);
- kassert(FROMHOST_DEV(fromhost) == 1 && FROMHOST_CMD(fromhost) == 0);
+ // we should only be interrupted by keypresses
+ if (!(FROMHOST_DEV(fromhost) == 1 && FROMHOST_CMD(fromhost) == 0))
+ die("unexpected htif interrupt");
HLS()->console_ibuf = 1 + (uint8_t)FROMHOST_DATA(fromhost);
set_csr(mip, MIP_SSIP);
}
@@ -59,6 +62,12 @@ static uintptr_t mcall_htif_syscall(uintptr_t magic_mem)
return 0;
}
+void poweroff()
+{
+ while (1)
+ write_csr(mtohost, 1);
+}
+
void printm(const char* s, ...)
{
char buf[256];
@@ -116,9 +125,7 @@ static uintptr_t mcall_clear_ipi()
static uintptr_t mcall_shutdown()
{
- while (1)
- write_csr(mtohost, 1);
- return 0;
+ poweroff();
}
static uintptr_t mcall_set_timer(unsigned long long when)
@@ -153,12 +160,10 @@ void software_interrupt()
static void send_ipi_many(uintptr_t* pmask, int event)
{
- kassert(MAX_HARTS <= 8 * sizeof(*pmask));
+ _Static_assert(MAX_HARTS <= 8 * sizeof(*pmask), "# harts > uintptr_t bits");
uintptr_t mask = -1;
- if (pmask) {
- kassert(supervisor_paddr_valid((uintptr_t)pmask, sizeof(uintptr_t)));
+ if (pmask)
mask = *pmask;
- }
// send IPIs to everyone
for (ssize_t i = num_harts-1; i >= 0; i--)
@@ -238,7 +243,6 @@ void redirect_trap(uintptr_t epc, uintptr_t mstatus)
uintptr_t prev_priv = EXTRACT_FIELD(mstatus, MSTATUS_MPP);
uintptr_t prev_ie = EXTRACT_FIELD(mstatus, MSTATUS_MPIE);
- kassert(prev_priv <= PRV_S);
mstatus = INSERT_FIELD(mstatus, MSTATUS_SPP, prev_priv);
mstatus = INSERT_FIELD(mstatus, MSTATUS_SPIE, prev_ie);
mstatus = INSERT_FIELD(mstatus, MSTATUS_MPP, PRV_S);
diff --git a/pk/mtrap.h b/pk/mtrap.h
index fe44c58..b6ea1df 100644
--- a/pk/mtrap.h
+++ b/pk/mtrap.h
@@ -1,13 +1,19 @@
#ifndef _PK_MTRAP_H
#define _PK_MTRAP_H
-#include "pk.h"
#include "bits.h"
#include "encoding.h"
+#ifdef __riscv_atomic
+# define MAX_HARTS 8 // arbitrary
+#else
+# define MAX_HARTS 1
+#endif
+
#ifndef __ASSEMBLER__
#include "sbi.h"
+#include <stdint.h>
#define read_const_csr(reg) ({ unsigned long __tmp; \
asm ("csrr %0, " #reg : "=r"(__tmp)); \
@@ -23,6 +29,9 @@ static inline int xlen()
return read_const_csr(misa) < 0 ? 64 : 32;
}
+extern uintptr_t mem_size;
+extern uint32_t num_harts;
+
typedef uintptr_t csr_t; // TODO this might become uint128_t for RV128
typedef struct {
@@ -53,7 +62,12 @@ void hls_init(uint32_t hart_id, csr_t* csrs);
#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
#define OTHER_HLS(id) ((hls_t*)((void*)HLS() + RISCV_PGSIZE * ((id) - read_const_csr(mhartid))))
-#define printk printm
+void parse_config_string();
+void poweroff(void) __attribute((noreturn));
+void printm(const char* s, ...);
+#define assert(x) ({ if (!(x)) die("assertion failed: %s", #x); })
+#define die(str, ...) ({ printm("%s:%d: " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); poweroff(); })
+#define printk(...) die("printk")
#endif // !__ASSEMBLER__
diff --git a/pk/pk.c b/pk/pk.c
index d3f6b3e..8a0e588 100644
--- a/pk/pk.c
+++ b/pk/pk.c
@@ -1,4 +1,5 @@
#include "pk.h"
+#include "boot.h"
#include "vm.h"
#include "elf.h"
diff --git a/pk/pk.h b/pk/pk.h
index 917b841..280ad6a 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -3,16 +3,8 @@
#ifndef _PK_H
#define _PK_H
-#ifdef __riscv_atomic
-# define MAX_HARTS 8 // arbitrary
-#else
-# define MAX_HARTS 1
-#endif
-
#ifndef __ASSEMBLER__
-#define debug_printk(s, ...) //printk(s, __VA_ARGS__)
-
#include "encoding.h"
#include <stdint.h>
#include <string.h>
@@ -28,11 +20,6 @@ typedef struct
long insn;
} trapframe_t;
-struct mainvars {
- uint64_t argc;
- uint64_t argv[127]; // this space is shared with the arg strings themselves
-};
-
#define panic(s,...) do { do_panic(s"\n", ##__VA_ARGS__); } while(0)
#define kassert(cond) do { if(!(cond)) kassert_fail(""#cond); } while(0)
void do_panic(const char* s, ...) __attribute__((noreturn));
@@ -41,18 +28,12 @@ void kassert_fail(const char* s) __attribute__((noreturn));
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
-#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
-#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
-
#ifdef __cplusplus
extern "C" {
#endif
-extern uintptr_t mem_size;
extern int have_vm;
-extern uint32_t num_harts;
-struct mainvars* parse_args(struct mainvars*);
void printk(const char* s, ...);
void printm(const char* s, ...);
int vsnprintf(char* out, size_t n, const char* s, va_list vl);
@@ -60,42 +41,12 @@ int snprintf(char* out, size_t n, const char* s, ...);
void init_tf(trapframe_t*, long pc, long sp);
void start_user(trapframe_t* tf) __attribute__((noreturn));
void dump_tf(trapframe_t*);
-void print_logo();
void unhandled_trap(trapframe_t*);
void handle_misaligned_load(trapframe_t*);
void handle_misaligned_store(trapframe_t*);
void handle_fault_load(trapframe_t*);
void handle_fault_store(trapframe_t*);
-void prepare_supervisor_mode();
-void boot_loader(struct mainvars*);
-void run_loaded_program(struct mainvars*);
-void parse_config_string();
-void boot_other_hart();
-
-typedef struct {
- int phent;
- int phnum;
- int is_supervisor;
- size_t phdr;
- size_t phdr_size;
- size_t first_free_paddr;
- size_t first_user_vaddr;
- size_t first_vaddr_after_user;
- size_t bias;
- size_t entry;
- size_t brk_min;
- size_t brk;
- size_t brk_max;
- size_t mmap_max;
- size_t stack_bottom;
- size_t stack_top;
- size_t t0;
-} elf_info;
-
-extern elf_info current;
-
-void load_elf(const char* fn, elf_info* info);
static inline int insn_len(long insn)
{
@@ -120,7 +71,4 @@ static inline void wfi()
#endif // !__ASSEMBLER__
-#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
-#define ROUNDDOWN(a, b) ((a)/(b)*(b))
-
#endif
diff --git a/pk/pk.mk.in b/pk/pk.mk.in
index 0189666..78f826e 100644
--- a/pk/pk.mk.in
+++ b/pk/pk.mk.in
@@ -4,6 +4,7 @@ pk_subproject_deps = \
pk_hdrs = \
atomic.h \
bits.h \
+ boot.h \
elf.h \
emulation.h \
encoding.h \
@@ -19,6 +20,7 @@ pk_hdrs = \
vm.h \
pk_c_srcs = \
+ snprintf.c \
mtrap.c \
minit.c \
emulation.c \
diff --git a/pk/sbi_impl.c b/pk/sbi_impl.c
index bd352fe..4af0cd4 100644
--- a/pk/sbi_impl.c
+++ b/pk/sbi_impl.c
@@ -1,9 +1,6 @@
-#include "pk.h"
-#include "vm.h"
-#include "frontend.h"
+#include "mtrap.h"
#include "sbi.h"
-#include "mcall.h"
-#include <errno.h>
+#include "boot.h"
uintptr_t __sbi_query_memory(uintptr_t id, memory_block_info *p)
{
diff --git a/pk/snprintf.c b/pk/snprintf.c
new file mode 100644
index 0000000..1544a6c
--- /dev/null
+++ b/pk/snprintf.c
@@ -0,0 +1,98 @@
+// See LICENSE for license details.
+
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+int vsnprintf(char* out, size_t n, const char* s, va_list vl)
+{
+ bool format = false;
+ bool longarg = false;
+ size_t pos = 0;
+ for( ; *s; s++)
+ {
+ if(format)
+ {
+ switch(*s)
+ {
+ case 'l':
+ longarg = true;
+ break;
+ case 'p':
+ longarg = true;
+ if (++pos < n) out[pos-1] = '0';
+ if (++pos < n) out[pos-1] = 'x';
+ case 'x':
+ {
+ long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
+ for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--) {
+ int d = (num >> (4*i)) & 0xF;
+ if (++pos < n) out[pos-1] = (d < 10 ? '0'+d : 'a'+d-10);
+ }
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 'd':
+ {
+ long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
+ if (num < 0) {
+ num = -num;
+ if (++pos < n) out[pos-1] = '-';
+ }
+ long digits = 1;
+ for (long nn = num; nn /= 10; digits++)
+ ;
+ for (int i = digits-1; i >= 0; i--) {
+ if (pos + i + 1 < n) out[pos + i] = '0' + (num % 10);
+ num /= 10;
+ }
+ pos += digits;
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 's':
+ {
+ const char* s2 = va_arg(vl, const char*);
+ while (*s2) {
+ if (++pos < n)
+ out[pos-1] = *s2;
+ s2++;
+ }
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 'c':
+ {
+ if (++pos < n) out[pos-1] = (char)va_arg(vl,int);
+ longarg = false;
+ format = false;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if(*s == '%')
+ format = true;
+ else
+ if (++pos < n) out[pos-1] = *s;
+ }
+ if (pos < n)
+ out[pos] = 0;
+ else if (n)
+ out[n-1] = 0;
+ return pos;
+}
+
+int snprintf(char* out, size_t n, const char* s, ...)
+{
+ va_list vl;
+ va_start(vl, s);
+ int res = vsnprintf(out, n, s, vl);
+ va_end(vl);
+ return res;
+}
diff --git a/pk/syscall.c b/pk/syscall.c
index 6af78ee..17112d8 100644
--- a/pk/syscall.c
+++ b/pk/syscall.c
@@ -5,6 +5,7 @@
#include "file.h"
#include "frontend.h"
#include "vm.h"
+#include "boot.h"
#include <string.h>
#include <errno.h>
@@ -41,7 +42,7 @@ void sys_exit(int code)
}
}
- die(code);
+ shutdown(code);
}
ssize_t sys_read(int fd, char* buf, size_t n)
diff --git a/pk/vm.c b/pk/vm.c
index 3f5cb30..c29434d 100644
--- a/pk/vm.c
+++ b/pk/vm.c
@@ -2,6 +2,8 @@
#include "file.h"
#include "atomic.h"
#include "pk.h"
+#include "boot.h"
+#include "mtrap.h"
#include <stdint.h>
#include <errno.h>
diff --git a/pk/vm.h b/pk/vm.h
index 4a24e56..c05a1ce 100644
--- a/pk/vm.h
+++ b/pk/vm.h
@@ -28,11 +28,6 @@
#define MAP_POPULATE 0x8000
#define MREMAP_FIXED 0x2
-#define supervisor_paddr_valid(start, length) \
- ((uintptr_t)(start) >= current.first_user_vaddr + current.bias \
- && (uintptr_t)(start) + (length) < mem_size \
- && (uintptr_t)(start) + (length) >= (uintptr_t)(start))
-
void vm_init();
void supervisor_vm_init();
uintptr_t pk_vm_init();