From 80447e5711461fa58cf61d17a6a1b79f7dcd5294 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 5 Mar 2016 14:34:18 -0800 Subject: Disentangle PK and BBL a bit --- pk/bbl.c | 5 +-- pk/bits.h | 6 ++++ pk/boot.h | 47 ++++++++++++++++++++++++++ pk/configstring.c | 11 ++++--- pk/console.c | 96 +---------------------------------------------------- pk/elf.c | 9 ++--- pk/emulation.c | 2 +- pk/frontend.c | 2 +- pk/frontend.h | 2 +- pk/init.c | 8 +++-- pk/minit.c | 40 ++++++----------------- pk/mtrap.c | 28 +++++++++------- pk/mtrap.h | 18 ++++++++-- pk/pk.c | 1 + pk/pk.h | 52 ----------------------------- pk/pk.mk.in | 2 ++ pk/sbi_impl.c | 7 ++-- pk/snprintf.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pk/syscall.c | 3 +- pk/vm.c | 2 ++ pk/vm.h | 5 --- 21 files changed, 226 insertions(+), 218 deletions(-) create mode 100644 pk/boot.h create mode 100644 pk/snprintf.c 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 +#include + +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 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 #include -#include -#include - -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 #include #include @@ -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 +#include +#include 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 #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 #include @@ -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 +#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 +#include +#include +#include + +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 #include @@ -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 #include 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(); -- cgit v1.1