aboutsummaryrefslogtreecommitdiff
path: root/pk
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-04-06 11:00:56 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-04-06 11:01:16 -0700
commitee00503ebecb5f705c8d36c0325ae12afb66a10c (patch)
tree7f557de194ff83899d7d98ba36f7a1418bff7af4 /pk
parent0eface07b9c2a565b2fcf95fff3fc755811bfb4e (diff)
downloadpk-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.c7
-rw-r--r--pk/pk.c57
-rw-r--r--pk/pk.h6
-rw-r--r--pk/syscall.c26
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!");
}
diff --git a/pk/pk.c b/pk/pk.c
index 2737048..6878811 100644
--- a/pk/pk.c
+++ b/pk/pk.c
@@ -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);
diff --git a/pk/pk.h b/pk/pk.h
index c86d596..2c68c93 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -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);
}