1 #ifdef DEBUG_SUPPORT 2 3 #ifndef DEBUG_H 4 #define DEBUG_H 5 6 #include "../atomics.h" 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 #include "../defines.h" 13 #include <stdint.h> 14 #include <stdbool.h> 15 16 #define VERSION_DBG 0x0004 17 18 /* main user interface */ 19 /* please read the comments */ 20 21 /* reason for debug trigger */ 22 enum { 23 DBG_USER, /* request to open the debugger externally */ 24 DBG_READY, /* if reset, debugger ready for new commands */ 25 DBG_FROZEN, /* di \ halt */ 26 DBG_BREAKPOINT, /* hit a breakpoint */ 27 DBG_WATCHPOINT_READ, /* hit a read watchpoint */ 28 DBG_WATCHPOINT_WRITE, /* hit a write watchpoint */ 29 DBG_PORT_READ, /* read a monitored port */ 30 DBG_PORT_WRITE, /* wrote a monitored port */ 31 DBG_NMI_TRIGGERED, /* triggered a non maskable interrupt */ 32 DBG_WATCHDOG_TIMEOUT, /* watchdog timer reset */ 33 DBG_MISC_RESET, /* miscellaneous reset */ 34 DBG_STEP, /* step command executed */ 35 DBG_NUMBER 36 }; 37 38 /* available software commands */ 39 enum { 40 CMD_NONE, 41 CMD_ABORT, /* abort() routine hit */ 42 CMD_DEBUG, /* debugger() routine hit */ 43 CMD_SET_BREAKPOINT, /* enable breakpoint: DE=address */ 44 CMD_REM_BREAKPOINT, /* remove breakpoint: DE=address */ 45 CMD_SET_R_WATCHPOINT, /* set read watchpoint: DE=address | C=length */ 46 CMD_SET_W_WATCHPOINT, /* set write watchpoint: DE=address | C=length */ 47 CMD_SET_RW_WATCHPOINT, /* set read/write watchpoint: DE=address | C=length */ 48 CMD_REM_WATCHPOINT, /* remove watchpoint: DE=address */ 49 CMD_REM_ALL_BREAK, /* remove all breakpoints */ 50 CMD_REM_ALL_WATCH, /* remove all watchpoints */ 51 CMD_SET_E_WATCHPOINT, /* set empty watchpoint: DE=address | C=length */ 52 CMD_NUMBER 53 }; 54 55 /* interface functions */ 56 void debug_init(void); /* call before starting emulation */ 57 void debug_free(void); /* call after emulation end */ 58 void debug_set_pc(uint32_t addr); /* when in gui debug set program counter */ 59 void debug_inst_start(void); 60 void debug_inst_fetch(void); 61 void debug_inst_repeat(void); 62 void debug_record_call(uint32_t retAddr, bool stack); 63 void debug_record_ret(uint32_t retAddr, bool stack); 64 void debug_watch(uint32_t addr, int mask, bool set); /* set a breakpoint or a watchpoint */ 65 void debug_ports(uint16_t addr, int mask, bool set); /* set port monitor flags */ 66 void debug_flag(int mask, bool set); /* configure setup of debug core */ 67 void debug_step(int mode, uint32_t addr); /* set a step mode, addr points to the instruction after pc */ 68 void debug_open(int reason, uint32_t data); /* open the debugger (Should only be called from gui_do_stuff) */ 69 bool debug_is_open(void); /* returns the status of the core debugger */ 70 71 /* masks */ 72 #define DBG_MASK_NONE (0 << 0) 73 #define DBG_IGNORE (1 << 0) /* ignore any breakpoints, watchpoints, or similar */ 74 #define DBG_SOFT_COMMANDS (1 << 1) /* allow software commands from executing code */ 75 #define DBG_OPEN_ON_RESET (1 << 2) /* open the debugger when a reset is triggered */ 76 77 /* port monitoring */ 78 #define DBG_MASK_PORT_READ (1 << 0) /* port monitor reads */ 79 #define DBG_MASK_PORT_WRITE (1 << 1) /* port monitor writes */ 80 #define DBG_MASK_PORT_FREEZE (1 << 2) /* port freeze value */ 81 82 /* breakpoints / watchpoints */ 83 #define DBG_MASK_READ (1 << 0) /* read watchpoint */ 84 #define DBG_MASK_WRITE (1 << 1) /* write watchpoint */ 85 #define DBG_MASK_EXEC (1 << 2) /* breakpoint */ 86 #define DBG_MASK_RW ((DBG_MASK_READ) | (DBG_MASK_WRITE)) 87 88 89 /* internal items below this line */ 90 #define DBG_INST_START_MARKER (1 << 3) 91 #define DBG_INST_MARKER (1 << 4) 92 93 #define DBG_PORT_RANGE 0xFFFF00 94 #define DBGOUT_PORT_RANGE 0xFB0000 95 #define DBGERR_PORT_RANGE 0xFC0000 96 #define DBGEXT_PORT 0xFD0000 97 #define DBG_STACK_SIZE 0x100 98 #define DBG_STACK_MASK (DBG_STACK_SIZE-1) 99 #define DBG_ADDR_SIZE 0x1000000 100 #define DBG_PORT_SIZE 0x10000 101 #define SIZEOF_DBG_BUFFER 0x1000 102 103 typedef struct { 104 bool mode : 1; 105 bool popped : 1; 106 uint32_t stack : 24; 107 uint32_t retAddr : 24; 108 uint8_t range : 8; 109 } debug_stack_entry_t; 110 111 typedef struct { 112 uint32_t cpuNext; 113 uint32_t cpuCycles; 114 uint64_t cpuBaseCycles; 115 uint64_t cpuHaltCycles; 116 int64_t totalCycles, dmaCycles; 117 bool step, stepOver; 118 uint32_t tempExec, stepOut; 119 120 uint32_t stackIndex, stackSize; 121 debug_stack_entry_t *stack; 122 123 char buffer[SIZEOF_DBG_BUFFER]; 124 char bufferErr[SIZEOF_DBG_BUFFER]; 125 uint32_t bufErrPos; 126 uint32_t bufPos; 127 128 uint8_t *addr; 129 uint8_t *port; 130 _Atomic(int) flags; 131 _Atomic(bool) open; 132 _Atomic(bool) ignore; 133 _Atomic(bool) commands; 134 _Atomic(bool) openOnReset; 135 } debug_state_t; 136 137 extern debug_state_t debug; 138 139 enum { 140 DBG_STEP_IN=DBG_STEP+1, 141 DBG_STEP_OUT, 142 DBG_STEP_OVER, 143 DBG_STEP_NEXT, 144 DBG_RUN_UNTIL 145 }; 146 147 /* internal core functions */ 148 void debug_step_switch(void); 149 void debug_clear_step(void); 150 151 #ifdef __cplusplus 152 } 153 #endif 154 155 #endif 156 157 #endif 158