dsp563xx: Adding breakpoint/watchpoint support.
[openocd.git] / src / target / dsp563xx_once.c
index 416cb6b598087aa71b5d0797960a037751f747b5..aa8c96910c5238649b0e4d51f8c67588aea8752a 100644 (file)
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include <helper/jim.h>
+#include <jim.h>
 
 #include "target.h"
 #include "target_type.h"
 #include "dsp563xx.h"
 #include "dsp563xx_once.h"
 
-/** single word instruction */
-static int dsp563xx_once_ir_exec(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
-                         uint8_t go, uint8_t ex)
+#define JTAG_STATUS_STATIC_MASK                0x03
+#define JTAG_STATUS_STATIC_VALUE       0x01
+
+#define JTAG_STATUS_NORMAL             0x01
+#define JTAG_STATUS_STOPWAIT           0x05
+#define JTAG_STATUS_BUSY               0x09
+#define JTAG_STATUS_DEBUG              0x0d
+
+#define JTAG_INSTR_EXTEST              0x00
+#define JTAG_INSTR_SAMPLE_PRELOAD      0x01
+#define JTAG_INSTR_IDCODE              0x02
+#define JTAG_INSTR_HIZ                 0x04
+#define JTAG_INSTR_CLAMP               0x05
+#define JTAG_INSTR_ENABLE_ONCE         0x06
+#define JTAG_INSTR_DEBUG_REQUEST       0x07
+#define JTAG_INSTR_BYPASS              0x0F
+
+/** */
+static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out, int dr_len, int rti)
 {
-       dsp563xx_write_dr_u8(tap, 0,
-                            instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
-       dsp563xx_execute_queue();
+       jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);
 
        return ERROR_OK;
 }
 
+/** */
+static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out, int dr_len, int rti)
+{
+       return dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);
+}
+
+/** */
+static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti)
+{
+       return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti);
+}
+
 /** single word instruction */
-static int dsp563xx_once_ir_exec_nq(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
-                            uint8_t go, uint8_t ex)
+static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex)
+{
+       int err;
+
+       err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush)
+               err = jtag_execute_queue();
+       return err;
+}
+
+/* IR and DR functions */
+static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out, int ir_len, int rti)
 {
-       dsp563xx_write_dr_u8(tap, 0,
-                            instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
+       jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);
 
        return ERROR_OK;
 }
 
-/** once read register */
-int dsp563xx_once_reg_read(struct jtag_tap *tap, uint8_t reg, uint32_t * data)
+static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out, int ir_len, int rti)
 {
-       uint32_t dr_in;
+       return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
+}
 
-       dr_in = 0;
+static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out)
+{
+       return dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1);
+}
 
-       dsp563xx_once_ir_exec(tap, reg, 1, 0, 0);
-       dsp563xx_write_dr_u32(tap, &dr_in, 0x00, 24, 0);
-       dsp563xx_execute_queue();
+/** */
+int dsp563xx_once_target_status(struct jtag_tap *tap)
+{
+       int err;
+       uint8_t jtag_status;
 
-       *data = dr_in;
+       err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE);
+       if (err != ERROR_OK)
+               return TARGET_UNKNOWN;
+       err = jtag_execute_queue();
+       if (err != ERROR_OK)
+               return TARGET_UNKNOWN;
 
-       return ERROR_OK;
+       /* verify correct static status pattern */
+       if ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE)
+               return TARGET_UNKNOWN;
+
+       if (jtag_status != JTAG_STATUS_DEBUG)
+               return TARGET_RUNNING;
+
+       return TARGET_HALTED;
 }
 
-/** once write register */
-int dsp563xx_once_reg_write(struct jtag_tap *tap, uint8_t reg, uint32_t data)
+/** */
+int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)
 {
-       dsp563xx_once_ir_exec(tap, reg, 0, 0, 0);
-       dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
-       dsp563xx_execute_queue();
+       int err;
+       uint8_t ir_in = 0, pattern = 0;
+       uint32_t retry = 0;
+
+       /* in reset state we only get a ACK
+        * from the interface */
+       if (reset_state)
+               pattern = 1;
+       else
+               pattern = JTAG_STATUS_DEBUG;
+
+       /* wait until we get the ack */
+       while (ir_in != pattern) {
+               err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST);
+               if (err != ERROR_OK)
+                       return err;
+               err = jtag_execute_queue();
+               if (err != ERROR_OK)
+                       return err;
+
+               LOG_DEBUG("debug request: %02X", ir_in);
+
+               if (retry++ == 100)
+                       return ERROR_TARGET_FAILURE;
+       }
+
+       /* we cant enable the once in reset state */
+       if (pattern == 1)
+               return ERROR_OK;
+
+       /* try to enable once */
+       retry = 0;
+       ir_in = 0;
+       while (ir_in != pattern) {
+               err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
+               if (err != ERROR_OK)
+                       return err;
+               err = jtag_execute_queue();
+               if (err != ERROR_OK)
+                       return err;
+
+               LOG_DEBUG("enable once: %02X", ir_in);
+
+               if (retry++ == 100) {
+                       LOG_DEBUG("error");
+                       return ERROR_TARGET_FAILURE;
+               }
+       }
+
+       if (ir_in != JTAG_STATUS_DEBUG)
+               return ERROR_TARGET_FAILURE;
 
        return ERROR_OK;
 }
 
-/** single word instruction */
-int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, uint32_t opcode)
+/** once read registers */
+int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len)
 {
-       dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
-       dsp563xx_execute_queue();
+       int i;
+       int err = ERROR_OK;
 
-       return ERROR_OK;
+       for (i = 0; i < len; i++) {
+               err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);
+               if (err != ERROR_OK)
+                       return err;
+       }
+
+       if (flush)
+               err = jtag_execute_queue();
+       return err;
 }
 
-/** double word instruction */
-int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode,
-                               uint32_t operand)
+/** once read register with register len */
+int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data)
 {
-       dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0);
-       dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
-       dsp563xx_execute_queue();
+       int err;
 
-       dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
-       dsp563xx_execute_queue();
+       err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush)
+               err = jtag_execute_queue();
 
-       return ERROR_OK;
+       return err;
+}
+
+/** once read register */
+int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data)
+{
+       int err;
+
+       err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush)
+               err = jtag_execute_queue();
+
+       return err;
+}
+
+/** once write register */
+int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data)
+{
+       int err;
+
+       err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush)
+               err = jtag_execute_queue();
+       return err;
 }
 
 /** single word instruction */
-int dsp563xx_once_execute_sw_ir_nq(struct jtag_tap *tap, uint32_t opcode)
+int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode)
 {
-       dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
+       int err;
 
-       return ERROR_OK;
+       err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush)
+               err = jtag_execute_queue();
+       return err;
 }
 
 /** double word instruction */
-int dsp563xx_once_execute_dw_ir_nq(struct jtag_tap *tap, uint32_t opcode,
-                                  uint32_t operand)
+int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand)
 {
-       dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0);
-       dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
+       int err;
+
+       err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush) {
+               err = jtag_execute_queue();
+               if (err != ERROR_OK)
+                       return err;
+       }
 
-       dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
+       err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
+       if (err != ERROR_OK)
+               return err;
+       err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
+       if (err != ERROR_OK)
+               return err;
+       if (flush) {
+               err = jtag_execute_queue();
+               if (err != ERROR_OK)
+                       return err;
+       }
 
        return ERROR_OK;
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)