diff --git a/common/nanoBench.c b/common/nanoBench.c index 9381f31..8a7c493 100644 --- a/common/nanoBench.c +++ b/common/nanoBench.c @@ -329,6 +329,27 @@ void write_msr(unsigned int msr, uint64_t value) { #endif } +void change_bit_in_msr(unsigned int msr, unsigned int bit, bool bit_value) { + uint64_t msr_value = read_msr(msr); + msr_value &= ~((uint64_t)1 << bit); + msr_value |= ((uint64_t)bit_value << bit); + write_msr(msr, msr_value); +} + +void set_bit_in_msr(unsigned int msr, unsigned int bit) { + change_bit_in_msr(msr, bit, true); +} + +void clear_bit_in_msr(unsigned int msr, unsigned int bit) { + change_bit_in_msr(msr, bit, false); +} + +uint64_t read_pmc(unsigned int counter) { + unsigned long lo, hi; + asm volatile("rdpmc" : "=a"(lo), "=d"(hi) : "c"(counter)); + return lo | ((uint64_t)hi) << 32; +} + void clear_perf_counters() { if (is_Intel_CPU) { for (int i=0; i<3; i++) { @@ -375,6 +396,18 @@ void disable_perf_ctrs_globally() { } } +void enable_freeze_on_PMI(void) { + if (is_Intel_CPU) { + set_bit_in_msr(MSR_IA32_DEBUGCTL, 12); + } +} + +void disable_freeze_on_PMI(void) { + if (is_Intel_CPU) { + clear_bit_in_msr(MSR_IA32_DEBUGCTL, 12); + } +} + void configure_perf_ctrs_FF_Intel(bool usr, bool os) { uint64_t fixed_ctrl = 0; fixed_ctrl |= (os << 8) | (os << 4) | os; diff --git a/common/nanoBench.h b/common/nanoBench.h index 41bc311..38abd2d 100644 --- a/common/nanoBench.h +++ b/common/nanoBench.h @@ -232,6 +232,11 @@ uint64_t read_value_from_cmd(char* cmd); uint64_t read_msr(unsigned int msr); void write_msr(unsigned int msr, uint64_t value); +void change_bit_in_msr(unsigned int msr, unsigned int bit, bool bit_value); +void set_bit_in_msr(unsigned int msr, unsigned int bit); +void clear_bit_in_msr(unsigned int msr, unsigned int bit); + +uint64_t read_pmc(unsigned int counter); void clear_perf_counters(void); void clear_perf_counter_configurations(void); @@ -240,6 +245,9 @@ void clear_overflow_status_bits(void); void enable_perf_ctrs_globally(void); void disable_perf_ctrs_globally(void); +void enable_freeze_on_PMI(void); +void disable_freeze_on_PMI(void); + // Enables the fixed-function performance counters locally. void configure_perf_ctrs_FF_Intel(bool usr, bool os);