dsp563xx: add x, y and p memory access
[openocd.git] / src / target / dsp563xx_once.c
index edca7f416ce7872fba55c00ac81edefc620cedd0..df43ed6e6cb71426395965163809abd4cfdc718c 100644 (file)
 #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_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_CLAMP               0x03
+#define JTAG_INSTR_HIZ                 0x04
+#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();
+       if (NULL == tap)
+       {
+               LOG_ERROR("invalid tap");
+               return ERROR_FAIL;
+       }
+
+       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)
+{
+       if (dr_len > 8)
+       {
+               LOG_ERROR("dr_len overflow, maxium is 8");
+               return ERROR_FAIL;
+       }
+
+       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)
+{
+       if (dr_len > 32)
+       {
+               LOG_ERROR("dr_len overflow, maxium is 32");
+               return ERROR_FAIL;
+       }
+
+       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, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex)
 {
-       dsp563xx_write_dr_u8(tap, 0,
-                            instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
+       int err;
+
+       if ((err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0)) != ERROR_OK)
+               return err;
+
+       return jtag_execute_queue();
+}
+
+/** single word instruction */
+static inline inline int dsp563xx_once_ir_exec_nq(struct jtag_tap *tap, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex)
+{
+       return dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
+}
+
+/* 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)
+{
+       if (NULL == tap)
+       {
+               LOG_ERROR("invalid tap");
+               return ERROR_FAIL;
+       }
+       if (ir_len != tap->ir_length)
+       {
+               LOG_ERROR("invalid ir_len");
+               return ERROR_FAIL;
+       }
+
+       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;
+       if (ir_len > 8)
+       {
+               LOG_ERROR("ir_len overflow, maxium is 8");
+               return ERROR_FAIL;
+       }
 
-       dr_in = 0;
+       return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
+}
 
-       dsp563xx_once_ir_exec(tap, reg, 1, 0, 0);
-       dsp563xx_write_dr_u32(tap, &dr_in, 0x00, 24, 0);
-       dsp563xx_execute_queue();
+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);
+}
 
-       *data = dr_in;
+/** */
+int dsp563xx_once_target_status(struct jtag_tap *tap)
+{
+       int err;
+       uint8_t jtag_status;
+
+       if ((err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE)) != ERROR_OK)
+               return err;
+       if ((err = jtag_execute_queue()) != ERROR_OK)
+               return err;
+
+       if ((jtag_status & 1) != 1)
+       {
+               return TARGET_UNKNOWN;
+       }
+
+       if (jtag_status != JTAG_STATUS_DEBUG)
+       {
+               return TARGET_RUNNING;
+       }
+
+       return TARGET_HALTED;
+}
+
+/** */
+int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)
+{
+       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)
+       {
+               if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST)) != ERROR_OK)
+                       return err;
+               if ((err = jtag_execute_queue()) != 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)
+       {
+               if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE)) != ERROR_OK)
+                       return err;
+               if ((err = jtag_execute_queue()) != 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;
 }
 
+/** once read registers */
+int dsp563xx_once_read_register(struct jtag_tap *tap, struct once_reg *regs, int len)
+{
+       int i;
+       int err;
+
+       for (i = 0; i < len; i++)
+       {
+               if ((err = dsp563xx_once_reg_read_ex_nq(tap, regs[i].addr, regs[i].len, &regs[i].reg)) != ERROR_OK)
+                       return err;
+       }
+
+       return jtag_execute_queue();
+/*
+       for(i=0;i<len;i++)
+       {
+               printf("%08X\n",regs[i].reg);
+       }
+*/
+}
+
+/** once read register */
+int dsp563xx_once_reg_read_ex_nq(struct jtag_tap *tap, uint8_t reg, uint8_t len, uint32_t * data)
+{
+       int err;
+
+       if ((err = dsp563xx_once_ir_exec(tap, reg, 1, 0, 0)) != ERROR_OK)
+               return err;
+       return dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);
+}
+
+/** once read register */
+int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, uint8_t reg, uint8_t len, uint32_t * data)
+{
+       int err;
+
+       if ((err = dsp563xx_once_ir_exec(tap, reg, 1, 0, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0)) != ERROR_OK)
+               return err;
+       return jtag_execute_queue();
+}
+
+/** once read register */
+int dsp563xx_once_reg_read(struct jtag_tap *tap, uint8_t reg, uint32_t * data)
+{
+       int err;
+
+       if ((err = dsp563xx_once_ir_exec(tap, reg, 1, 0, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0)) != ERROR_OK)
+               return err;
+       return jtag_execute_queue();
+}
+
 /** once write register */
 int dsp563xx_once_reg_write(struct jtag_tap *tap, uint8_t reg, uint32_t data)
 {
-       dsp563xx_once_ir_exec(tap, reg, 0, 0, 0);
-       dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
-       dsp563xx_execute_queue();
+       int err;
 
-       return ERROR_OK;
+       if ((err = dsp563xx_once_ir_exec(tap, reg, 0, 0, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0)) != ERROR_OK)
+               return err;
+       return jtag_execute_queue();
 }
 
 /** single word instruction */
 int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, uint32_t opcode)
 {
-       dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
-       dsp563xx_execute_queue();
+       int err;
 
-       return ERROR_OK;
+       if ((err = dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK)
+               return err;
+       return jtag_execute_queue();
 }
 
 /** double word instruction */
-int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode,
-                               uint32_t operand)
+int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode, uint32_t operand)
 {
-       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();
+       if ((err = dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK)
+               return err;
+       if ((err = jtag_execute_queue()) != ERROR_OK)
+               return err;
+
+       if ((err = dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0)) != ERROR_OK)
+               return err;
+       if ((err = jtag_execute_queue()) != ERROR_OK)
+               return err;
 
        return ERROR_OK;
 }
@@ -104,21 +325,29 @@ int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode,
 /** single word instruction */
 int dsp563xx_once_execute_sw_ir_nq(struct jtag_tap *tap, 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;
+
+       if ((err = dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK)
+               return err;
 
        return ERROR_OK;
 }
 
 /** 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_nq(struct jtag_tap *tap, 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;
 
-       dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
-       dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
+       if ((err = dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK)
+               return err;
+       if ((err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0)) != 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)