diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-04-06 11:00:56 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2016-04-06 11:01:16 -0700 |
commit | ee00503ebecb5f705c8d36c0325ae12afb66a10c (patch) | |
tree | 7f557de194ff83899d7d98ba36f7a1418bff7af4 /pk | |
parent | 0eface07b9c2a565b2fcf95fff3fc755811bfb4e (diff) | |
download | pk-ee00503ebecb5f705c8d36c0325ae12afb66a10c.zip pk-ee00503ebecb5f705c8d36c0325ae12afb66a10c.tar.gz pk-ee00503ebecb5f705c8d36c0325ae12afb66a10c.tar.bz2 |
Don't assume existence of uarch counters
Diffstat (limited to 'pk')
-rw-r--r-- | pk/handlers.c | 7 | ||||
-rw-r--r-- | pk/pk.c | 57 | ||||
-rw-r--r-- | pk/pk.h | 6 | ||||
-rw-r--r-- | pk/syscall.c | 26 |
4 files changed, 46 insertions, 50 deletions
diff --git a/pk/handlers.c b/pk/handlers.c index 1961852..71466b8 100644 --- a/pk/handlers.c +++ b/pk/handlers.c @@ -14,6 +14,13 @@ static void handle_illegal_instruction(trapframe_t* tf) else kassert(len == 2); + // supply 0 for unimplemented uarch counters + if ((tf->insn & (MASK_CSRRS | 0xcc0U<<20)) == (MATCH_CSRRS | 0xcc0U<<20)) { + tf->gpr[(tf->insn >> 7) & 0x1f] = 0; + tf->epc += 4; + return; + } + dump_tf(tf); panic("An illegal instruction was executed!"); } @@ -4,12 +4,45 @@ #include "elf.h" #include "mtrap.h" #include "frontend.h" +#include <stdbool.h> elf_info current; -int uarch_counters_enabled; -long uarch_counters[NUM_COUNTERS]; -char* uarch_counter_names[NUM_COUNTERS]; +#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) { @@ -20,7 +53,6 @@ static void handle_option(const char* s) 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; @@ -116,22 +148,7 @@ 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(); - 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 - } + start_uarch_counters(); trapframe_t tf; init_tf(&tf, current.entry, stack_top); @@ -35,6 +35,7 @@ int vsnprintf(char* out, size_t n, const char* s, va_list vl); int snprintf(char* out, size_t n, const char* s, ...); void start_user(trapframe_t* tf) __attribute__((noreturn)); void dump_tf(trapframe_t*); +void dump_uarch_counters(); static inline int insn_len(long insn) { @@ -43,11 +44,6 @@ static inline int insn_len(long insn) #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) -#define NUM_COUNTERS (18) -extern int uarch_counters_enabled; -extern long uarch_counters[NUM_COUNTERS]; -extern char* uarch_counter_names[NUM_COUNTERS]; - #ifdef __cplusplus } #endif diff --git a/pk/syscall.c b/pk/syscall.c index de11a0a..66c07ef 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -17,31 +17,7 @@ void sys_exit(int code) { if (current.t0) printk("%ld cycles\n", rdcycle() - current.t0); - - if (uarch_counters_enabled) { - size_t i = 0; - #define READ_CTR_FINI(name) do { \ - while (i >= NUM_COUNTERS) ; \ - long csr = read_csr(name); \ - csr -= uarch_counters[i]; uarch_counter_names[i] = #name; \ - uarch_counters[i++] = csr; \ - } while (0) - READ_CTR_FINI(cycle); READ_CTR_FINI(instret); - READ_CTR_FINI(uarch0); READ_CTR_FINI(uarch1); READ_CTR_FINI(uarch2); - READ_CTR_FINI(uarch3); READ_CTR_FINI(uarch4); READ_CTR_FINI(uarch5); - READ_CTR_FINI(uarch6); READ_CTR_FINI(uarch7); READ_CTR_FINI(uarch8); - READ_CTR_FINI(uarch9); READ_CTR_FINI(uarch10); READ_CTR_FINI(uarch11); - READ_CTR_FINI(uarch12); READ_CTR_FINI(uarch13); READ_CTR_FINI(uarch14); - READ_CTR_FINI(uarch15); - #undef READ_CTR_FINI - - for (int i = 0; i < NUM_COUNTERS; i++) { - if (uarch_counters[i]) { - printk("%s = %ld\n", uarch_counter_names[i], uarch_counters[i]); - } - } - } - + dump_uarch_counters(); shutdown(code); } |