mips32, change in pracc_list for dynamic allocation
authorSalvador Arroyo <sarroyofdez@yahoo.es>
Sun, 26 Feb 2017 08:11:02 +0000 (09:11 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Mon, 8 May 2017 16:57:30 +0000 (17:57 +0100)
pracc_list points to an array with code in the lower half
and addr in the upper half. Change it to a struct with
an instruction field and an address field.
Requiered to make reallocation easier.
As a side effect the code is less quirky.

Change-Id: Ibf904a33a2f35a7f69284d2a2114f4b4ae79219f
Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>
Reviewed-on: http://openocd.zylin.com/4019
Tested-by: jenkins
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
src/target/mips32_pracc.c
src/target/mips32_pracc.h
src/target/mips_ejtag.c

index 45d22427313b181e8d26c37bc17ea47e2d843953..c55688b462cd919e1f75f69a49bba910170ba690 100644 (file)
@@ -235,18 +235,17 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
                                                restart = 1;
                                                continue;
                                        }
-
                                        return ERROR_JTAG_DEVICE_ERROR;
                                }
                                /* check for store instruction at dmseg */
-                               uint32_t store_addr = ctx->pracc_list[ctx->max_code + code_count];
+                               uint32_t store_addr = ctx->pracc_list[code_count].addr;
                                if (store_addr != 0) {
                                        if (store_addr > max_store_addr)
                                                max_store_addr = store_addr;
                                        store_pending++;
                                }
 
-                               instr = ctx->pracc_list[code_count++];
+                               instr = ctx->pracc_list[code_count++].instr;
                                if (code_count == ctx->code_count)      /* last instruction, start final check */
                                        final_check = 1;
 
@@ -306,7 +305,7 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
        ctx->code_count = 0;
        ctx->store_count = 0;
 
-       ctx->pracc_list = malloc(2 * ctx->max_code * sizeof(uint32_t));
+       ctx->pracc_list = malloc(ctx->max_code * sizeof(pa_list));
        if (ctx->pracc_list == NULL) {
                LOG_ERROR("Out of memory");
                ctx->retval = ERROR_FAIL;
@@ -315,8 +314,8 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
 
 inline void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
 {
-       ctx->pracc_list[ctx->max_code + ctx->code_count] = addr;
-       ctx->pracc_list[ctx->code_count++] = instr;
+       ctx->pracc_list[ctx->code_count].instr = instr;
+       ctx->pracc_list[ctx->code_count++].addr = addr;
        if (addr)
                ctx->store_count++;
 }
@@ -367,16 +366,16 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
        mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
 
        int scan_count = 0;
-       for (int i = 0; i != 2 * ctx->code_count; i++) {
-               uint32_t data = 0;
-               if (i & 1u) {                   /* Check store address from previous instruction, if not the first */
-                       if (i < 2 || 0 == ctx->pracc_list[ctx->max_code + (i / 2) - 1])
-                               continue;
-               } else
-                       data = ctx->pracc_list[i / 2];
-
+       for (int i = 0; i != ctx->code_count; i++) {
                jtag_add_clocks(num_clocks);
-               mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, data, scan_in[scan_count++].scan_96);
+               mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, ctx->pracc_list[i].instr,
+                                      scan_in[scan_count++].scan_96);
+
+               /* Check store address from previous instruction, if not the first */
+               if (i > 0 && ctx->pracc_list[i - 1].addr) {
+                       jtag_add_clocks(num_clocks);
+                       mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, 0, scan_in[scan_count++].scan_96);
+               }
        }
 
        int retval = jtag_execute_queue();              /* execute queued scans */
@@ -385,24 +384,35 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
 
        uint32_t fetch_addr = MIPS32_PRACC_TEXT;                /* start address */
        scan_count = 0;
-       for (int i = 0; i != 2 * ctx->code_count; i++) {                                /* verify every pracc access */
-               uint32_t store_addr = 0;
-               if (i & 1u) {                   /* Read store addres from previous instruction, if not the first */
-                       store_addr = ctx->pracc_list[ctx->max_code + (i / 2) - 1];
-                       if (i < 2 || 0 == store_addr)
-                               continue;
-               }
-
+       for (int i = 0; i != ctx->code_count; i++) {                            /* verify every pracc access */
+               /* check pracc bit */
                ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+               uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
                if (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) {
                        LOG_ERROR("Error: access not pending  count: %d", scan_count);
                        retval = ERROR_FAIL;
                        goto exit;
                }
+               if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
+                       LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
+                       retval = ERROR_FAIL;
+                       goto exit;
+               }
+               if (addr != fetch_addr) {
+                       LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
+                                         addr, fetch_addr, scan_count);
+                       retval = ERROR_FAIL;
+                       goto exit;
+               }
+               fetch_addr += 4;
+               scan_count++;
 
-               uint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
+               /* check if previous intrucction is a store instruction at dmesg */
+               if (i > 0 && ctx->pracc_list[i - 1].addr) {
+                       uint32_t store_addr = ctx->pracc_list[i - 1].addr;
+                       ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);
+                       addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);
 
-               if (store_addr != 0) {
                        if (!(ejtag_ctrl & EJTAG_CTRL_PRNW)) {
                                LOG_ERROR("Not a store/write access, count: %d", scan_count);
                                retval = ERROR_FAIL;
@@ -410,28 +420,14 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
                        }
                        if (addr != store_addr) {
                                LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
-                                               addr, store_addr, scan_count);
+                                                             addr, store_addr, scan_count);
                                retval = ERROR_FAIL;
                                goto exit;
                        }
                        int buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;
                        buf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);
-
-               } else {
-                       if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
-                               LOG_ERROR("Not a fetch/read access, count: %d", scan_count);
-                               retval = ERROR_FAIL;
-                               goto exit;
-                       }
-                       if (addr != fetch_addr) {
-                               LOG_ERROR("Fetch addr mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d",
-                                         addr, fetch_addr, scan_count);
-                               retval = ERROR_FAIL;
-                               goto exit;
-                       }
-                       fetch_addr += 4;
+                       scan_count++;
                }
-               scan_count++;
        }
 exit:
        free(scan_in);
index 2ede5b28809f78cda6e00c8899bc01c966396940..166cbb46592d7e226c2674863f0996b1578fdc84 100644 (file)
 #define NEG16(v)                                               (((~(v)) + 1) & 0xFFFF)
 /*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/
 
+typedef struct {
+       uint32_t instr;
+       uint32_t addr;
+} pa_list;
+
 struct pracc_queue_info {
        int retval;
        const int max_code;
        int code_count;
        int store_count;
-       uint32_t *pracc_list;   /* Code and store addresses */
+       pa_list *pracc_list;    /* Code and store addresses at dmseg */
 };
 void pracc_queue_init(struct pracc_queue_info *ctx);
 void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr);
index 1fbdf3ceff93fae26e034396b85a3effdf5be631..943a868225cadb5a08386b7155b471c98e4fd6e2 100644 (file)
@@ -272,8 +272,8 @@ error:
 
 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
 {
-       uint32_t pracc_list[] = {MIPS32_DRET, 0};
-       struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = pracc_list, .code_count = 1, .store_count = 0};
+       pa_list pracc_list = {.instr = MIPS32_DRET, .addr = 0};
+       struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
 
        /* execute our dret instruction */
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);