X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fmips32_pracc.c;h=87e712bc5de591d3e2b23cace27364c37645bcf3;hb=4315142ea0d7035fe117b9e344beaf98c91ee35c;hp=3ac294958ae0ac366b56233372cdeb2593771cc0;hpb=83f3f2c4c70d60035eb7ec6e8a5f78f92ecb01e3;p=openocd.git diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 3ac294958a..87e712bc5d 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -93,18 +93,6 @@ struct mips32_pracc_context { struct mips_ejtag *ejtag_info; }; -static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, - uint32_t addr, uint32_t *buf); - -static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint8_t *buf); -static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint16_t *buf); -static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint32_t *buf); -static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, - uint32_t addr, uint32_t *buf); - static int mips32_pracc_sync_cache(struct mips_ejtag *ejtag_info, uint32_t start_addr, uint32_t end_addr); static int mips32_pracc_clean_invalidate_cache(struct mips_ejtag *ejtag_info, @@ -206,11 +194,7 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad if (retval != ERROR_OK) return retval; - if ((address >= MIPS32_PRACC_PARAM_IN) - && (address < MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) { - offset = (address - MIPS32_PRACC_PARAM_IN) / 4; - ctx->local_iparam[offset] = data; - } else if ((address >= MIPS32_PRACC_PARAM_OUT) + if ((address >= MIPS32_PRACC_PARAM_OUT) && (address < MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) { offset = (address - MIPS32_PRACC_PARAM_OUT) / 4; ctx->local_oparam[offset] = data; @@ -286,6 +270,26 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_ return ERROR_OK; } +static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) +{ + uint32_t code[] = { + /* start: */ + MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ + MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR), /* $15 = MIPS32_PRACC_BASE_ADDR */ + MIPS32_SW(8, PRACC_STACK_OFFSET, 15), /* sw $8,PRACC_STACK_OFFSET($15) */ + + MIPS32_LUI(8, UPPER16((addr + 0x8000))), /* load $8 with modified upper address */ + MIPS32_LW(8, LOWER16(addr), 8), /* lw $8, LOWER16(addr)($8) */ + MIPS32_SW(8, PRACC_OUT_OFFSET, 15), /* sw $8,PRACC_OUT_OFFSET($15) */ + + MIPS32_LW(8, PRACC_STACK_OFFSET, 15), /* lw $8,PRACC_STACK_OFFSET($15) */ + MIPS32_B(NEG16(8)), /* b start */ + MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ + }; + + return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, buf, 1); +} + int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) { if (count == 1 && size == 4) @@ -387,26 +391,6 @@ exit: return retval; } -static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) -{ - uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR), /* $15 = MIPS32_PRACC_BASE_ADDR */ - MIPS32_SW(8, PRACC_STACK_OFFSET, 15), /* sw $8,PRACC_STACK_OFFSET($15) */ - - MIPS32_LUI(8, UPPER16((addr + 0x8000))), /* load $8 with modified upper address */ - MIPS32_LW(8, LOWER16(addr), 8), /* lw $8, LOWER16(addr)($8) */ - MIPS32_SW(8, PRACC_OUT_OFFSET, 15), /* sw $8,PRACC_OUT_OFFSET($15) */ - - MIPS32_LW(8, PRACC_STACK_OFFSET, 15), /* lw $8,PRACC_STACK_OFFSET($15) */ - MIPS32_B(NEG16(8)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ - }; - - return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, buf, 1); -} - int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel) { /** @@ -619,28 +603,102 @@ static int mips32_pracc_clean_invalidate_cache(struct mips_ejtag *ejtag_info, return retval; } - -int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) +static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) { - int retval; + uint32_t *code; + code = malloc((128 * 3 + 9) * sizeof(uint32_t)); /* alloc memory for the worst case */ + if (code == NULL) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } - switch (size) { - case 1: - retval = mips32_pracc_write_mem8(ejtag_info, addr, count, (uint8_t *)buf); - break; - case 2: - retval = mips32_pracc_write_mem16(ejtag_info, addr, count, (uint16_t *)buf); - break; - case 4: - if (count == 1) - retval = mips32_pracc_write_u32(ejtag_info, addr, (uint32_t *)buf); - else - retval = mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t *)buf); - break; - default: - retval = ERROR_FAIL; + uint32_t *buf32 = buf; + uint16_t *buf16 = buf; + uint8_t *buf8 = buf; + + int i; + int retval = ERROR_FAIL; + uint32_t *code_p; + uint32_t upper_base_addr, last_upper_base_addr; + int this_round_count; + int code_len; + + while (count) { + this_round_count = (count > 128) ? 128 : count; + last_upper_base_addr = UPPER16((addr + 0x8000)); + code_p = code; + + *code_p++ = MIPS32_MTC0(15, 31, 0); /* save $15 in DeSave */ + *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR); /* $15 = MIPS32_PRACC_BASE_ADDR */ + *code_p++ = MIPS32_SW(8, PRACC_STACK_OFFSET, 15); /* save $8 to pracc stack */ + *code_p++ = MIPS32_LUI(15, last_upper_base_addr); /* reuse $15 as memory base address */ + code_len = 4; + + for (i = 0; i != this_round_count; i++) { + upper_base_addr = UPPER16((addr + 0x8000)); + if (last_upper_base_addr != upper_base_addr) { + *code_p++ = MIPS32_LUI(15, upper_base_addr); /* if needed, change upper address in $15*/ + code_len++; + last_upper_base_addr = upper_base_addr; + } + + if (size == 4) { /* for word write check if one half word is 0 and load it accordingly */ + if (LOWER16(*buf32) == 0) { + *code_p++ = MIPS32_LUI(8, UPPER16(*buf32)); /* load only upper value */ + code_len++; + } else if (UPPER16(*buf32) == 0) { + *code_p++ = MIPS32_ORI(8, 0, LOWER16(*buf32)); /* load only lower value */ + code_len++; + } else { + *code_p++ = MIPS32_LUI(8, UPPER16(*buf32)); /* load upper and lower */ + *code_p++ = MIPS32_ORI(8, 8, LOWER16(*buf32)); + code_len += 2; + } + *code_p++ = MIPS32_SW(8, LOWER16(addr), 15); /* store word to memory */ + code_len++; + buf32++; + + } else if (size == 2) { + *code_p++ = MIPS32_ORI(8, 0, *buf16); /* load lower value */ + *code_p++ = MIPS32_SH(8, LOWER16(addr), 15); /* store half word to memory */ + code_len += 2; + buf16++; + + } else { + *code_p++ = MIPS32_ORI(8, 0, *buf8); /* load lower value */ + *code_p++ = MIPS32_SB(8, LOWER16(addr), 15); /* store byte to memory */ + code_len += 2; + buf8++; + } + + addr += size; + } + + *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR); /* $15 = MIPS32_PRACC_BASE_ADDR */ + *code_p++ = MIPS32_LW(8, PRACC_STACK_OFFSET, 15); /* restore $8 from pracc stack */ + + code_len += 4; + *code_p++ = MIPS32_B(NEG16(code_len - 1)); /* jump to start */ + *code_p = MIPS32_MFC0(15, 31, 0); /* restore $15 from DeSave */ + + retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1); + if (retval != ERROR_OK) + goto exit; + + count -= this_round_count; } +exit: + free(code); + return retval; +} + +int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) +{ + int retval = mips32_pracc_write_mem_generic(ejtag_info, addr, size, count, buf); + if (retval != ERROR_OK) + return retval; + /** * If we are in the cachable regoion and cache is activated, * we must clean D$ + invalidate I$ after we did the write, @@ -703,342 +761,99 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz return retval; } -static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) -{ - static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(8, 0, 15), /* sw $8,($15) */ - MIPS32_SW(9, 0, 15), /* sw $9,($15) */ - MIPS32_SW(10, 0, 15), /* sw $10,($15) */ - MIPS32_SW(11, 0, 15), /* sw $11,($15) */ - - MIPS32_ADDI(8, 15, NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)), /* $8= MIPS32_PRACC_PARAM_IN */ - MIPS32_LW(9, 0, 8), /* Load write addr to $9 */ - MIPS32_LW(10, 4, 8), /* Load write count to $10 */ - MIPS32_ADDI(8, 8, 8), /* $8 += 8 beginning of data */ - - /* loop: */ - MIPS32_LW(11, 0, 8), /* lw $11,0($8), Load $11 with the word @mem[$8] */ - MIPS32_SW(11, 0, 9), /* sw $11,0($9) */ - - MIPS32_ADDI(9, 9, 4), /* $9 += 4 */ - MIPS32_BNE(10, 9, NEG16(4)), /* bne $10, $9, loop */ - MIPS32_ADDI(8, 8, 4), /* $8 += 4 */ - - /* end: */ - MIPS32_LW(11, 0, 15), /* lw $11,($15) */ - MIPS32_LW(10, 0, 15), /* lw $10,($15) */ - MIPS32_LW(9, 0, 15), /* lw $9,($15) */ - MIPS32_LW(8, 0, 15), /* lw $8,($15) */ - MIPS32_B(NEG16(21)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ - }; - - /* TODO remove array */ - uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t)); - param_in[0] = addr; - param_in[1] = addr + (count * sizeof(uint32_t)); /* last address */ - - memcpy(¶m_in[2], buf, count * sizeof(uint32_t)); - - int retval; - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - count + 2, param_in, 0, NULL, 1); - - free(param_in); - - return retval; -} - -static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) -{ - static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(8, 0, 15), /* sw $8,($15) */ - MIPS32_SW(9, 0, 15), /* sw $9,($15) */ - - MIPS32_LW(8, NEG16((MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)-4), 15), /* load R8 @ param_in[1] = data */ - MIPS32_LW(9, NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN), 15), /* load R9 @ param_in[0] = address */ - - MIPS32_SW(8, 0, 9), /* sw $8,0($9) */ - - MIPS32_LW(9, 0, 15), /* lw $9,($15) */ - MIPS32_LW(8, 0, 15), /* lw $8,($15) */ - MIPS32_B(NEG16(11)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ - }; - - /* TODO remove array */ - uint32_t param_in[1 + 1]; - param_in[0] = addr; - param_in[1] = *buf; - - return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - ARRAY_SIZE(param_in), param_in, 0, NULL, 1); -} - -static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) -{ - static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(8, 0, 15), /* sw $8,($15) */ - MIPS32_SW(9, 0, 15), /* sw $9,($15) */ - MIPS32_SW(10, 0, 15), /* sw $10,($15) */ - MIPS32_SW(11, 0, 15), /* sw $11,($15) */ - - MIPS32_LUI(8, UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */ - MIPS32_ORI(8, 8, LOWER16(MIPS32_PRACC_PARAM_IN)), - MIPS32_LW(9, 0, 8), /* Load write addr to $9 */ - MIPS32_LW(10, 4, 8), /* Load write count to $10 */ - MIPS32_ADDI(8, 8, 8), /* $8 += 8 */ - /* loop: */ - MIPS32_BEQ(0, 10, 8), /* beq $0, $10, end */ - MIPS32_NOP, - - MIPS32_LW(11, 0, 8), /* lw $11,0($8), Load $11 with the word @mem[$8] */ - MIPS32_SH(11, 0, 9), /* sh $11,0($9) */ - - MIPS32_ADDI(10, 10, NEG16(1)), /* $10-- */ - MIPS32_ADDI(9, 9, 2), /* $9 += 2 */ - MIPS32_ADDI(8, 8, 4), /* $8 += 4 */ - - MIPS32_B(NEG16(8)), /* b loop */ - MIPS32_NOP, - /* end: */ - MIPS32_LW(11, 0, 15), /* lw $11,($15) */ - MIPS32_LW(10, 0, 15), /* lw $10,($15) */ - MIPS32_LW(9, 0, 15), /* lw $9,($15) */ - MIPS32_LW(8, 0, 15), /* lw $8,($15) */ - MIPS32_B(NEG16(26)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ - }; - - /* TODO remove array */ - uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t)); - int i; - param_in[0] = addr; - param_in[1] = count; - - for (i = 0; i < count; i++) - param_in[i + 2] = buf[i]; - - int retval; - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - count + 2, param_in, 0, NULL, 1); - - free(param_in); - - return retval; -} - -static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) +int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) { - static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(8, 0, 15), /* sw $8,($15) */ - MIPS32_SW(9, 0, 15), /* sw $9,($15) */ - MIPS32_SW(10, 0, 15), /* sw $10,($15) */ - MIPS32_SW(11, 0, 15), /* sw $11,($15) */ - - MIPS32_LUI(8, UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */ - MIPS32_ORI(8, 8, LOWER16(MIPS32_PRACC_PARAM_IN)), - MIPS32_LW(9, 0, 8), /* Load write addr to $9 */ - MIPS32_LW(10, 4, 8), /* Load write count to $10 */ - MIPS32_ADDI(8, 8, 8), /* $8 += 8 */ - /* loop: */ - MIPS32_BEQ(0, 10, 8), /* beq $0, $10, end */ - MIPS32_NOP, - - MIPS32_LW(11, 0, 8), /* lw $11,0($8), Load $11 with the word @mem[$8] */ - MIPS32_SB(11, 0, 9), /* sb $11,0($9) */ - - MIPS32_ADDI(10, 10, NEG16(1)), /* $10-- */ - MIPS32_ADDI(9, 9, 1), /* $9 += 1 */ - MIPS32_ADDI(8, 8, 4), /* $8 += 4 */ - - MIPS32_B(NEG16(8)), /* b loop */ - MIPS32_NOP, - /* end: */ - MIPS32_LW(11, 0, 15), /* lw $11,($15) */ - MIPS32_LW(10, 0, 15), /* lw $10,($15) */ - MIPS32_LW(9, 0, 15), /* lw $9,($15) */ - MIPS32_LW(8, 0, 15), /* lw $8,($15) */ - MIPS32_B(NEG16(26)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ + static const uint32_t cp0_write_code[] = { + MIPS32_MTC0(1, 12, 0), /* move $1 to status */ + MIPS32_MTLO(1), /* move $1 to lo */ + MIPS32_MTHI(1), /* move $1 to hi */ + MIPS32_MTC0(1, 8, 0), /* move $1 to badvaddr */ + MIPS32_MTC0(1, 13, 0), /* move $1 to cause*/ + MIPS32_MTC0(1, 24, 0), /* move $1 to depc (pc) */ }; - /* TODO remove array */ - uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t)); - int retval; - int i; - param_in[0] = addr; - param_in[1] = count; - - for (i = 0; i < count; i++) - param_in[i + 2] = buf[i]; - - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - count + 2, param_in, 0, NULL, 1); - - free(param_in); - - return retval; -} + uint32_t *code; + code = malloc((37 * 2 + 6 + 1) * sizeof(uint32_t)); /* alloc memory for the worst case */ + if (code == NULL) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } -int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) -{ - static const uint32_t code[] = { - /* start: */ - MIPS32_LUI(2, UPPER16(MIPS32_PRACC_PARAM_IN)), /* $2 = MIPS32_PRACC_PARAM_IN */ - MIPS32_ORI(2, 2, LOWER16(MIPS32_PRACC_PARAM_IN)), - MIPS32_LW(1, 1*4, 2), /* lw $1,1*4($2) */ - MIPS32_LW(15, 15*4, 2), /* lw $15,15*4($2) */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(1, 0, 15), /* sw $1,($15) */ - MIPS32_LUI(1, UPPER16(MIPS32_PRACC_PARAM_IN)), /* $1 = MIPS32_PRACC_PARAM_IN */ - MIPS32_ORI(1, 1, LOWER16(MIPS32_PRACC_PARAM_IN)), - MIPS32_LW(3, 3*4, 1), /* lw $3,3*4($1) */ - MIPS32_LW(4, 4*4, 1), /* lw $4,4*4($1) */ - MIPS32_LW(5, 5*4, 1), /* lw $5,5*4($1) */ - MIPS32_LW(6, 6*4, 1), /* lw $6,6*4($1) */ - MIPS32_LW(7, 7*4, 1), /* lw $7,7*4($1) */ - MIPS32_LW(8, 8*4, 1), /* lw $8,8*4($1) */ - MIPS32_LW(9, 9*4, 1), /* lw $9,9*4($1) */ - MIPS32_LW(10, 10*4, 1), /* lw $10,10*4($1) */ - MIPS32_LW(11, 11*4, 1), /* lw $11,11*4($1) */ - MIPS32_LW(12, 12*4, 1), /* lw $12,12*4($1) */ - MIPS32_LW(13, 13*4, 1), /* lw $13,13*4($1) */ - MIPS32_LW(14, 14*4, 1), /* lw $14,14*4($1) */ - MIPS32_LW(16, 16*4, 1), /* lw $16,16*4($1) */ - MIPS32_LW(17, 17*4, 1), /* lw $17,17*4($1) */ - MIPS32_LW(18, 18*4, 1), /* lw $18,18*4($1) */ - MIPS32_LW(19, 19*4, 1), /* lw $19,19*4($1) */ - MIPS32_LW(20, 20*4, 1), /* lw $20,20*4($1) */ - MIPS32_LW(21, 21*4, 1), /* lw $21,21*4($1) */ - MIPS32_LW(22, 22*4, 1), /* lw $22,22*4($1) */ - MIPS32_LW(23, 23*4, 1), /* lw $23,23*4($1) */ - MIPS32_LW(24, 24*4, 1), /* lw $24,24*4($1) */ - MIPS32_LW(25, 25*4, 1), /* lw $25,25*4($1) */ - MIPS32_LW(26, 26*4, 1), /* lw $26,26*4($1) */ - MIPS32_LW(27, 27*4, 1), /* lw $27,27*4($1) */ - MIPS32_LW(28, 28*4, 1), /* lw $28,28*4($1) */ - MIPS32_LW(29, 29*4, 1), /* lw $29,29*4($1) */ - MIPS32_LW(30, 30*4, 1), /* lw $30,30*4($1) */ - MIPS32_LW(31, 31*4, 1), /* lw $31,31*4($1) */ - - MIPS32_LW(2, 32*4, 1), /* lw $2,32*4($1) */ - MIPS32_MTC0(2, 12, 0), /* move $2 to status */ - MIPS32_LW(2, 33*4, 1), /* lw $2,33*4($1) */ - MIPS32_MTLO(2), /* move $2 to lo */ - MIPS32_LW(2, 34*4, 1), /* lw $2,34*4($1) */ - MIPS32_MTHI(2), /* move $2 to hi */ - MIPS32_LW(2, 35*4, 1), /* lw $2,35*4($1) */ - MIPS32_MTC0(2, 8, 0), /* move $2 to badvaddr */ - MIPS32_LW(2, 36*4, 1), /* lw $2,36*4($1) */ - MIPS32_MTC0(2, 13, 0), /* move $2 to cause*/ - MIPS32_LW(2, 37*4, 1), /* lw $2,37*4($1) */ - MIPS32_MTC0(2, 24, 0), /* move $2 to depc (pc) */ - - MIPS32_LW(2, 2*4, 1), /* lw $2,2*4($1) */ - MIPS32_LW(1, 0, 15), /* lw $1,($15) */ - MIPS32_B(NEG16(53)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ - }; + uint32_t *code_p = code; + int code_len = 0; + /* load registers 2 to 31 with lui an ori instructions, check if same instructions can be saved */ + for (int i = 2; i < 32; i++) { + if (LOWER16((regs[i])) == 0) { + *code_p++ = MIPS32_LUI(i, UPPER16((regs[i]))); /* if lower half word is 0, lui instruction only */ + code_len++; + } else if (UPPER16((regs[i])) == 0) { + *code_p++ = MIPS32_ORI(i, 0, LOWER16((regs[i]))); /* if upper half word is 0, ori with $0 only*/ + code_len++; + } else { + *code_p++ = MIPS32_LUI(i, UPPER16((regs[i]))); /* default, load with lui and ori instructions */ + *code_p++ = MIPS32_ORI(i, i, LOWER16((regs[i]))); + code_len += 2; + } + } - int retval; + for (int i = 0; i != 6; i++) { + *code_p++ = MIPS32_LUI(1, UPPER16((regs[i + 32]))); /* load CPO value in $1, with lui and ori */ + *code_p++ = MIPS32_ORI(1, 1, LOWER16((regs[i + 32]))); + *code_p++ = cp0_write_code[i]; /* write value from $1 to CPO register */ + code_len += 3; + } - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - MIPS32NUMCOREREGS, regs, 0, NULL, 1); + *code_p++ = MIPS32_LUI(1, UPPER16((regs[1]))); /* load upper half word in $1 */ + code_len += 3; + *code_p++ = MIPS32_B(NEG16(code_len - 1)), /* b start */ + *code_p = MIPS32_ORI(1, 1, LOWER16((regs[1]))); /* load lower half word in $1 */ + int retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1); + free(code); return retval; } int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) { - static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(2, 31, 0), /* move $2 to COP0 DeSave */ - MIPS32_LUI(2, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $2 = MIPS32_PRACC_PARAM_OUT */ - MIPS32_ORI(2, 2, LOWER16(MIPS32_PRACC_PARAM_OUT)), - MIPS32_SW(0, 0*4, 2), /* sw $0,0*4($2) */ - MIPS32_SW(1, 1*4, 2), /* sw $1,1*4($2) */ - MIPS32_SW(15, 15*4, 2), /* sw $15,15*4($2) */ - MIPS32_MFC0(2, 31, 0), /* move COP0 DeSave to $2 */ - MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(1, 0, 15), /* sw $1,($15) */ - MIPS32_SW(2, 0, 15), /* sw $2,($15) */ - MIPS32_LUI(1, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */ - MIPS32_ORI(1, 1, LOWER16(MIPS32_PRACC_PARAM_OUT)), - MIPS32_SW(2, 2*4, 1), /* sw $2,2*4($1) */ - MIPS32_SW(3, 3*4, 1), /* sw $3,3*4($1) */ - MIPS32_SW(4, 4*4, 1), /* sw $4,4*4($1) */ - MIPS32_SW(5, 5*4, 1), /* sw $5,5*4($1) */ - MIPS32_SW(6, 6*4, 1), /* sw $6,6*4($1) */ - MIPS32_SW(7, 7*4, 1), /* sw $7,7*4($1) */ - MIPS32_SW(8, 8*4, 1), /* sw $8,8*4($1) */ - MIPS32_SW(9, 9*4, 1), /* sw $9,9*4($1) */ - MIPS32_SW(10, 10*4, 1), /* sw $10,10*4($1) */ - MIPS32_SW(11, 11*4, 1), /* sw $11,11*4($1) */ - MIPS32_SW(12, 12*4, 1), /* sw $12,12*4($1) */ - MIPS32_SW(13, 13*4, 1), /* sw $13,13*4($1) */ - MIPS32_SW(14, 14*4, 1), /* sw $14,14*4($1) */ - MIPS32_SW(16, 16*4, 1), /* sw $16,16*4($1) */ - MIPS32_SW(17, 17*4, 1), /* sw $17,17*4($1) */ - MIPS32_SW(18, 18*4, 1), /* sw $18,18*4($1) */ - MIPS32_SW(19, 19*4, 1), /* sw $19,19*4($1) */ - MIPS32_SW(20, 20*4, 1), /* sw $20,20*4($1) */ - MIPS32_SW(21, 21*4, 1), /* sw $21,21*4($1) */ - MIPS32_SW(22, 22*4, 1), /* sw $22,22*4($1) */ - MIPS32_SW(23, 23*4, 1), /* sw $23,23*4($1) */ - MIPS32_SW(24, 24*4, 1), /* sw $24,24*4($1) */ - MIPS32_SW(25, 25*4, 1), /* sw $25,25*4($1) */ - MIPS32_SW(26, 26*4, 1), /* sw $26,26*4($1) */ - MIPS32_SW(27, 27*4, 1), /* sw $27,27*4($1) */ - MIPS32_SW(28, 28*4, 1), /* sw $28,28*4($1) */ - MIPS32_SW(29, 29*4, 1), /* sw $29,29*4($1) */ - MIPS32_SW(30, 30*4, 1), /* sw $30,30*4($1) */ - MIPS32_SW(31, 31*4, 1), /* sw $31,31*4($1) */ - + static int cp0_read_code[] = { MIPS32_MFC0(2, 12, 0), /* move status to $2 */ - MIPS32_SW(2, 32*4, 1), /* sw $2,32*4($1) */ MIPS32_MFLO(2), /* move lo to $2 */ - MIPS32_SW(2, 33*4, 1), /* sw $2,33*4($1) */ MIPS32_MFHI(2), /* move hi to $2 */ - MIPS32_SW(2, 34*4, 1), /* sw $2,34*4($1) */ MIPS32_MFC0(2, 8, 0), /* move badvaddr to $2 */ - MIPS32_SW(2, 35*4, 1), /* sw $2,35*4($1) */ MIPS32_MFC0(2, 13, 0), /* move cause to $2 */ - MIPS32_SW(2, 36*4, 1), /* sw $2,36*4($1) */ MIPS32_MFC0(2, 24, 0), /* move depc (pc) to $2 */ - MIPS32_SW(2, 37*4, 1), /* sw $2,37*4($1) */ - - MIPS32_LW(2, 0, 15), /* lw $2,($15) */ - MIPS32_LW(1, 0, 15), /* lw $1,($15) */ - MIPS32_B(NEG16(58)), /* b start */ - MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ }; - int retval; + uint32_t *code; + code = malloc(49 * sizeof(uint32_t)); + if (code == NULL) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + uint32_t *code_p = code; + + *code_p++ = MIPS32_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */ + *code_p++ = MIPS32_LUI(1, PRACC_UPPER_BASE_ADDR); /* $1 = MIP32_PRACC_BASE_ADDR */ + + for (int i = 2; i != 32; i++) + *code_p++ = MIPS32_SW(i, PRACC_OUT_OFFSET + (i * 4), 1); /* store GPR's 2 to 31 */ + + for (int i = 0; i != 6; i++) { + *code_p++ = cp0_read_code[i]; /* load COP0 needed registers to $2 */ + *code_p++ = MIPS32_SW(2, PRACC_OUT_OFFSET + (i + 32) * 4, 1); /* store COP0 registers from $2 to param out */ + } + + *code_p++ = MIPS32_MFC0(2, 31, 0), /* move DeSave to $2, reg1 value */ + *code_p++ = MIPS32_SW(2, PRACC_OUT_OFFSET + 4, 1); /* store reg1 value from $2 to param out */ + + *code_p++ = MIPS32_LW(2, PRACC_OUT_OFFSET + 8, 1); /* restore $2 from param out (singularity) */ + *code_p++ = MIPS32_B(NEG16(48)); /* b start */ + *code_p = MIPS32_MFC0(1, 31, 0); /* move COP0 DeSave to $1 */ - retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, - 0, NULL, MIPS32NUMCOREREGS, regs, 1); + int retval = mips32_pracc_exec(ejtag_info, 49, code, 0, NULL, MIPS32NUMCOREREGS, regs, 1); + free(code); return retval; } @@ -1105,7 +920,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are /* write program into RAM */ if (write_t != ejtag_info->fast_access_save) { - mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code); + mips32_pracc_write_mem_generic(ejtag_info, source->address, 4, ARRAY_SIZE(handler_code), handler_code); /* save previous operation to speed to any consecutive read/writes */ ejtag_info->fast_access_save = write_t; }