WIP. Doesn't work.
[riscv-isa-sim.git] / riscv / debug_module.h
index d7c1a87baa797e710f13072b27b033fe74665d4a..82c449ef6a70a699af5438db8a9adc83e353a356 100644 (file)
 
 #include "devices.h"
 
+class sim_t;
+
+typedef struct {
+  bool haltreq;
+  bool resumereq;
+  unsigned hartsel;
+  bool hartreset;
+  bool dmactive;
+  bool ndmreset;
+} dmcontrol_t;
+
+typedef struct {
+  bool impebreak;
+  bool allnonexistant;
+  bool anynonexistant;
+  bool allunavail;
+  bool anyunavail;
+  bool allrunning;
+  bool anyrunning;
+  bool allhalted;
+  bool anyhalted;
+  bool allresumeack;
+  bool anyresumeack;
+  bool authenticated;
+  bool authbusy;
+  bool cfgstrvalid;
+  unsigned version;
+} dmstatus_t;
+
+typedef enum cmderr {
+    CMDERR_NONE = 0,
+    CMDERR_BUSY = 1,
+    CMDERR_NOTSUP = 2,
+    CMDERR_EXCEPTION = 3,
+    CMDERR_HALTRESUME = 4,
+    CMDERR_OTHER = 7  
+} cmderr_t;
+
+typedef struct {
+  bool busy;
+  unsigned datacount;
+  unsigned progbufsize;
+  cmderr_t cmderr;
+} abstractcs_t;
+
+typedef struct {
+  unsigned autoexecprogbuf;
+  unsigned autoexecdata;
+} abstractauto_t;
+
+typedef struct {
+  unsigned version;
+  bool readonaddr;
+  unsigned sbaccess;
+  bool autoincrement;
+  bool readondata;
+  unsigned error;
+  unsigned asize;
+  bool access128;
+  bool access64;
+  bool access32;
+  bool access16;
+  bool access8;
+} sbcs_t;
+
 class debug_module_t : public abstract_device_t
 {
   public:
+    debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits);
+    ~debug_module_t();
+
+    void add_device(bus_t *bus);
+
     bool load(reg_t addr, size_t len, uint8_t* bytes);
     bool store(reg_t addr, size_t len, const uint8_t* bytes);
 
-    void ram_write32(unsigned int index, uint32_t value);
-    uint32_t ram_read32(unsigned int index);
-
-    void set_interrupt(uint32_t hartid) {
-      fprintf(stderr, "set debug interrupt 0x%x\n", hartid);
-      interrupt.insert(hartid);
-    }
-    void clear_interrupt(uint32_t hartid) {
-      fprintf(stderr, "clear debug interrupt 0x%x\n", hartid);
-      interrupt.erase(hartid);
-    }
-    bool get_interrupt(uint32_t hartid) const {
-      return interrupt.find(hartid) != interrupt.end();
-    }
+    // Debug Module Interface that the debugger (in our case through JTAG DTM)
+    // uses to access the DM.
+    // Return true for success, false for failure.
+    bool dmi_read(unsigned address, uint32_t *value);
+    bool dmi_write(unsigned address, uint32_t value);
 
   private:
-    // Track which interrupts from module to debugger are set.
-    std::set<uint32_t> interrupt;
-    char debug_ram[DEBUG_RAM_SIZE];
+    static const unsigned datasize = 2;
+    // Size of program_buffer in 32-bit words, as exposed to the rest of the
+    // world.
+    unsigned progbufsize;
+    // Actual size of the program buffer, which is 1 word bigger than we let on
+    // to implement the implicit ebreak at the end.
+    unsigned program_buffer_bytes;
+    unsigned max_bus_master_bits ;
+    static const unsigned debug_data_start = 0x380;
+    unsigned debug_progbuf_start;
+
+    static const unsigned debug_abstract_size = 5;
+    unsigned debug_abstract_start;
+
+    static const unsigned hartsellen = 10;
+
+    sim_t *sim;
+
+    uint8_t debug_rom_whereto[4];
+    uint8_t debug_abstract[debug_abstract_size * 4];
+    uint8_t *program_buffer;
+    uint8_t dmdata[datasize * 4];
+    
+    bool halted[1024];
+    bool resumeack[1024];
+    uint8_t debug_rom_flags[1024];
+
+    void write32(uint8_t *rom, unsigned int index, uint32_t value);
+    uint32_t read32(uint8_t *rom, unsigned int index);
+
+    void sb_autoincrement();
+    void sb_read();
+    void sb_write();
+    unsigned sb_access_bits();
+
+    dmcontrol_t dmcontrol;
+    dmstatus_t dmstatus;
+    abstractcs_t abstractcs;
+    abstractauto_t abstractauto;
+    uint32_t command;
+
+    sbcs_t sbcs;
+    uint32_t sbaddress[4];
+    uint32_t sbdata[4];
+
+    processor_t *current_proc() const;
+    void reset();
+    bool perform_abstract_command();
 };
 
 #endif