1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
// See LICENSE for license details.
#include "pk.h"
#include "boot.h"
#include "file.h"
#include "vm.h"
#include "frontend.h"
#include "elf.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
elf_info current;
int have_vm = 1; // unless -p flag is given
int uarch_counters_enabled;
long uarch_counters[NUM_COUNTERS];
char* uarch_counter_names[NUM_COUNTERS];
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 handle_option(const char* s)
{
switch (s[1])
{
case 's': // print cycle count upon termination
current.t0 = 1;
break;
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;
default:
panic("unrecognized option: `%c'", s[1]);
break;
}
}
#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;
}
void boot_loader()
{
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], ¤t);
run_loaded_program(argc, args.argv);
}
|