|
|
|
@ -8,42 +8,6 @@ |
|
|
|
|
|
|
|
elf_info current; |
|
|
|
|
|
|
|
#define NUM_COUNTERS 18 |
|
|
|
static int uarch_counters_enabled; |
|
|
|
static long uarch_counters[NUM_COUNTERS]; |
|
|
|
static char* uarch_counter_names[NUM_COUNTERS]; |
|
|
|
|
|
|
|
static void read_uarch_counters(bool dump) |
|
|
|
{ |
|
|
|
if (!uarch_counters_enabled) |
|
|
|
return; |
|
|
|
|
|
|
|
size_t i = 0; |
|
|
|
#define READ_CTR(name) do { \ |
|
|
|
while (i >= NUM_COUNTERS) ; \ |
|
|
|
long csr = read_csr(name); \ |
|
|
|
if (dump && csr) printk("%s = %ld\n", #name, csr - uarch_counters[i]); \ |
|
|
|
uarch_counters[i++] = csr; \ |
|
|
|
} while (0) |
|
|
|
READ_CTR(0xcc0); READ_CTR(0xcc1); READ_CTR(0xcc2); |
|
|
|
READ_CTR(0xcc3); READ_CTR(0xcc4); READ_CTR(0xcc5); |
|
|
|
READ_CTR(0xcc6); READ_CTR(0xcc7); READ_CTR(0xcc8); |
|
|
|
READ_CTR(0xcc9); READ_CTR(0xcca); READ_CTR(0xccb); |
|
|
|
READ_CTR(0xccc); READ_CTR(0xccd); READ_CTR(0xcce); |
|
|
|
READ_CTR(0xccf); READ_CTR(cycle); READ_CTR(instret); |
|
|
|
#undef READ_CTR |
|
|
|
} |
|
|
|
|
|
|
|
static void start_uarch_counters() |
|
|
|
{ |
|
|
|
read_uarch_counters(false); |
|
|
|
} |
|
|
|
|
|
|
|
void dump_uarch_counters() |
|
|
|
{ |
|
|
|
read_uarch_counters(true); |
|
|
|
} |
|
|
|
|
|
|
|
static void handle_option(const char* s) |
|
|
|
{ |
|
|
|
switch (s[1]) |
|
|
|
@ -52,10 +16,6 @@ static void handle_option(const char* s) |
|
|
|
current.t0 = 1; |
|
|
|
break; |
|
|
|
|
|
|
|
case 'c': // print uarch counters upon termination
|
|
|
|
uarch_counters_enabled = 1; |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
panic("unrecognized option: `%c'", s[1]); |
|
|
|
break; |
|
|
|
@ -148,8 +108,6 @@ static void run_loaded_program(size_t argc, char** argv, uintptr_t kstack_top) |
|
|
|
if (current.t0) // start timer if so requested
|
|
|
|
current.t0 = rdcycle(); |
|
|
|
|
|
|
|
start_uarch_counters(); |
|
|
|
|
|
|
|
trapframe_t tf; |
|
|
|
init_tf(&tf, current.entry, stack_top); |
|
|
|
__clear_cache(0, 0); |
|
|
|
|