aboutsummaryrefslogtreecommitdiff
path: root/c_emulator/traploop_detector.cpp
blob: f8a6ecb215d121da177c82ebbd36f3db565dd333 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "traploop_detector.h"
#include "sail_riscv_model.h"
#include <cstdlib>
#include <inttypes.h>

traploop_detector::traploop_detector() {
  reset();
}

void traploop_detector::reset() {
  mepc_at_first_trap = 0;
  sepc_at_first_trap = 0;
  instrets_since_last_trap = 0;
  nested_trap_count = 0;
}

void traploop_detector::trap_callback(hart::Model &model, bool, fbits) {
  if (nested_trap_count == 0) {
    mepc_at_first_trap = model.zmepc.bits;
    sepc_at_first_trap = model.zsepc.bits;
  }
  nested_trap_count++;
  instrets_since_last_trap = 0;
}

void traploop_detector::xret_callback(hart::Model &, bool) {
  reset();
}

void traploop_detector::instret_callback(hart::Model &) {
  if (nested_trap_count != 0) {
    instrets_since_last_trap++;
    if (instrets_since_last_trap > instrets_to_reset_loop) {
      reset();
    }
  }
}

bool traploop_detector::loop_detected() const {
  return nested_trap_count > nested_trap_count_threshold;
}

uint64_t traploop_detector::mepc() const {
  return mepc_at_first_trap;
}

uint64_t traploop_detector::sepc() const {
  return sepc_at_first_trap;
}