diff options
author | Andrew Waterman <waterman@eecs.berkeley.edu> | 2014-08-07 21:38:14 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@eecs.berkeley.edu> | 2014-08-07 21:38:14 -0700 |
commit | 53385b7dbd3829f8d0773819dd475732d8820481 (patch) | |
tree | d35fec4f346b3a1992d6c52a16ca72957d36180c | |
parent | 92afb6f40797a68e2a16c9abd5cdb3c9336da307 (diff) | |
parent | 5eba64df88be49c4f2aaddeda3f3f81d7b4b34f3 (diff) | |
download | pk-53385b7dbd3829f8d0773819dd475732d8820481.zip pk-53385b7dbd3829f8d0773819dd475732d8820481.tar.gz pk-53385b7dbd3829f8d0773819dd475732d8820481.tar.bz2 |
Merge pull request #2 from ccelio/master
Added "-c" option to track uarch counter info.
-rw-r--r-- | pk/init.c | 26 | ||||
-rw-r--r-- | pk/pk.h | 5 | ||||
-rw-r--r-- | pk/syscall.c | 24 |
3 files changed, 55 insertions, 0 deletions
@@ -13,6 +13,10 @@ int have_vm = 1; // unless -p flag is given int have_fp; int have_accelerator; +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, int user64) { memset(tf,0,sizeof(*tf)); @@ -33,6 +37,11 @@ static void handle_option(const char* s) 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; + case 'p': // physical memory mode have_vm = 0; break; @@ -122,6 +131,23 @@ static void user_init(struct mainvars* args) 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 + } + trapframe_t tf; init_tf(&tf, current.entry, stack_top, current.elf64); __clear_cache(0, 0); @@ -82,6 +82,11 @@ 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 338ac74..f32bbe1 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -27,6 +27,30 @@ 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 = %d\n", uarch_counter_names[i], uarch_counters[i]); + } + } + } + frontend_syscall(SYS_exit, code, 0, 0, 0, 0); clear_csr(status, SR_EI); while (1); |