mips32, add realloc code 20/4020/5
authorSalvador Arroyo <sarroyofdez@yahoo.es>
Sun, 26 Feb 2017 19:35:01 +0000 (20:35 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Mon, 8 May 2017 16:59:15 +0000 (17:59 +0100)
If max_code is reached realloc memory. If fails to realloc
the error is propagated and every call to pracc_add() returns
immediately. The exec function logs the error.

Change-Id: Idd4ed9d9b8b19b7d6842d0bc5ebb05f943726705
Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>
Reviewed-on: http://openocd.zylin.com/4020
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 c55688b462cd919e1f75f69a49bba910170ba690..da1cee13c98ebc95ec3f7a527efed1b5d5b05339 100644 (file)
@@ -304,23 +304,31 @@ inline void pracc_queue_init(struct pracc_queue_info *ctx)
        ctx->retval = ERROR_OK;
        ctx->code_count = 0;
        ctx->store_count = 0;
-
-       ctx->pracc_list = malloc(ctx->max_code * sizeof(pa_list));
-       if (ctx->pracc_list == NULL) {
-               LOG_ERROR("Out of memory");
-               ctx->retval = ERROR_FAIL;
-       }
+       ctx->max_code = 0;
+       ctx->pracc_list = NULL;
 }
 
-inline void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
+void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)
 {
+       if (ctx->retval != ERROR_OK)    /* On previous out of memory, return */
+               return;
+       if (ctx->code_count == ctx->max_code) {
+               void *p = realloc(ctx->pracc_list, sizeof(pa_list) * (ctx->max_code + PRACC_BLOCK));
+               if (p) {
+                       ctx->max_code += PRACC_BLOCK;
+                       ctx->pracc_list = p;
+               } else {
+                       ctx->retval = ERROR_FAIL;       /* Out of memory */
+                       return;
+               }
+       }
        ctx->pracc_list[ctx->code_count].instr = instr;
        ctx->pracc_list[ctx->code_count++].addr = addr;
        if (addr)
                ctx->store_count++;
 }
 
-inline void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
+void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)
 {
        if (LOWER16(data) == 0 && optimize)
                pracc_add(ctx, 0, MIPS32_LUI(reg_num, UPPER16(data)));  /* load only upper value */
@@ -334,14 +342,17 @@ inline void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint3
 
 inline void pracc_queue_free(struct pracc_queue_info *ctx)
 {
-       if (ctx->code_count > ctx->max_code)    /* Only for internal check, will be erased */
-               LOG_ERROR("Internal error, code count: %d > max code: %d", ctx->code_count, ctx->max_code);
        if (ctx->pracc_list != NULL)
                free(ctx->pracc_list);
 }
 
 int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *buf)
 {
+       if (ctx->retval != ERROR_OK) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
        if (ejtag_info->mode == 0)
                return mips32_pracc_exec(ejtag_info, ctx, buf);
 
@@ -436,10 +447,8 @@ exit:
 
 int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
 {
-       struct pracc_queue_info ctx = {.max_code = 8};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));                      /* $15 = MIPS32_PRACC_BASE_ADDR */
        pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16((addr + 0x8000))));            /* load  $8 with modified upper address */
@@ -451,7 +460,6 @@ int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* move COP0 DeSave to $15 */
 
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf);
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -462,10 +470,8 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
                return mips32_pracc_read_u32(ejtag_info, addr, (uint32_t *)buf);
 
        uint32_t *data = NULL;
-       struct pracc_queue_info ctx = {.max_code = 256 * 3 + 8 + 1};    /* alloc memory for the worst case */
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        if (size != 4) {
                data = malloc(256 * sizeof(uint32_t));
@@ -541,10 +547,8 @@ exit:
 
 int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel)
 {
-       struct pracc_queue_info ctx = {.max_code = 7};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));                      /* $15 = MIPS32_PRACC_BASE_ADDR */
        pracc_add(&ctx, 0, MIPS32_MFC0(8, cp0_reg, cp0_sel));                   /* move cp0 reg / sel to $8 */
@@ -556,17 +560,14 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_r
        pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));                /* restore lower 16 bits of $8 */
 
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val);
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
 
 int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)
 {
-       struct pracc_queue_info ctx = {.max_code = 6};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        pracc_add_li32(&ctx, 15, val, 0);                               /* Load val to $15 */
 
@@ -575,7 +576,6 @@ int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_r
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                             /* restore $15 from DeSave */
 
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -610,10 +610,9 @@ exit:
 static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
                                         uint32_t start_addr, uint32_t end_addr, int cached, int rel)
 {
-       struct pracc_queue_info ctx = {.max_code = 256 * 2 + 5};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
+
        /** Find cache line size in bytes */
        uint32_t clsiz;
        if (rel) {      /* Release 2 (rel = 1) */
@@ -711,10 +710,8 @@ exit:
 static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,
                uint32_t addr, int size, int count, const void *buf)
 {
-       struct pracc_queue_info ctx = {.max_code = 128 * 3 + 5 + 1};    /* alloc memory for the worst case */
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        const uint32_t *buf32 = buf;
        const uint16_t *buf16 = buf;
@@ -834,10 +831,8 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
                MIPS32_MTC0(1, 24, 0),                                                  /* move $1 to depc (pc) */
        };
 
-       struct pracc_queue_info ctx = {.max_code = 37 * 2 + 7 + 1};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        /* load registers 2 to 31 with li32, optimize */
        for (int i = 2; i < 32; i++)
@@ -856,7 +851,6 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 
        ejtag_info->reg8 = regs[8];
        ejtag_info->reg9 = regs[9];
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -872,10 +866,8 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
                MIPS32_MFC0(8, 24, 0),                                                  /* move depc (pc) to $8 */
        };
 
-       struct pracc_queue_info ctx = {.max_code = 49};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        pracc_add(&ctx, 0, MIPS32_MTC0(1, 31, 0));                                              /* move $1 to COP0 DeSave */
        pracc_add(&ctx, 0, MIPS32_LUI(1, PRACC_UPPER_BASE_ADDR));                               /* $1 = MIP32_PRACC_BASE_ADDR */
@@ -901,7 +893,6 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 
        ejtag_info->reg8 = regs[8];     /* reg8 is saved but not restored, next called function should restore it */
        ejtag_info->reg9 = regs[9];
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
index 166cbb46592d7e226c2674863f0996b1578fdc84..525d6e618ec5646770e392cf8c7bfc306b04ad78 100644 (file)
@@ -42,6 +42,8 @@
 #define NEG16(v)                                               (((~(v)) + 1) & 0xFFFF)
 /*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/
 
+#define PRACC_BLOCK    128     /* 1 Kbyte */
+
 typedef struct {
        uint32_t instr;
        uint32_t addr;
@@ -49,13 +51,14 @@ typedef struct {
 
 struct pracc_queue_info {
        int retval;
-       const int max_code;
        int code_count;
        int store_count;
+       int max_code;           /* max intstructions with currently allocated memory */
        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);
+void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize);
 void pracc_queue_free(struct pracc_queue_info *ctx);
 int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info,
                            struct pracc_queue_info *ctx, uint32_t *buf);
index 943a868225cadb5a08386b7155b471c98e4fd6e2..1a8a843a89797d77fe0837f65f4fa63cdf200731 100644 (file)
@@ -197,10 +197,8 @@ void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
 /* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
 {
-       struct pracc_queue_info ctx = {.max_code = 7};
+       struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
-       if (ctx.retval != ERROR_OK)
-               goto exit;
 
        pracc_add(&ctx, 0, MIPS32_MFC0(8, 23, 0));                      /* move COP0 Debug to $8 */
        pracc_add(&ctx, 0, MIPS32_ORI(8, 8, 0x0100));                   /* set SSt bit in debug reg */
@@ -213,7 +211,6 @@ int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
        pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));        /* restore lower 16 bits of $8 */
 
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
-exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
 }

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)