aboutsummaryrefslogtreecommitdiff
path: root/riscv/jtag_dtm.h
blob: 23a54be1f7f982930c4909372a72e121a3964593 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef JTAG_DTM_H
#define JTAG_DTM_H

#include <stdint.h>

class debug_module_t;

typedef enum {
  TEST_LOGIC_RESET,
  RUN_TEST_IDLE,
  SELECT_DR_SCAN,
  CAPTURE_DR,
  SHIFT_DR,
  EXIT1_DR,
  PAUSE_DR,
  EXIT2_DR,
  UPDATE_DR,
  SELECT_IR_SCAN,
  CAPTURE_IR,
  SHIFT_IR,
  EXIT1_IR,
  PAUSE_IR,
  EXIT2_IR,
  UPDATE_IR
} jtag_state_t;

class jtag_dtm_t
{
  static const unsigned idcode = 0xdeadbeef;

  public:
    jtag_dtm_t(debug_module_t *dm, unsigned required_rti_cycles);
    void reset();

    void set_pins(bool tck, bool tms, bool tdi);

    bool tdo() const { return _tdo; }

    jtag_state_t state() const { return _state; }

  private:
    debug_module_t *dm;
    // The number of Run-Test/Idle cycles required before a DMI access is
    // complete.
    unsigned required_rti_cycles;
    bool _tck, _tms, _tdi, _tdo;
    uint32_t ir;
    const unsigned ir_length = 5;
    uint64_t dr;
    unsigned dr_length;

    // abits must come before dtmcontrol so it can easily be used in the
    // constructor.
    const unsigned abits = 6;
    uint32_t dtmcontrol;
    uint64_t dmi;
    unsigned bypass;
    // Number of Run-Test/Idle cycles needed before we call this access
    // complete.
    unsigned rti_remaining;
    bool busy_stuck;

    jtag_state_t _state;

    void capture_dr();
    void update_dr();
};

#endif