- u32 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 pc */
-
- MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */
- MIPS32_LW(1,0,15), /* lw $1,($15) */
- MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
- MIPS32_NOP,
- MIPS32_B(NEG16(55)), /* b start */
- MIPS32_NOP,
+ 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,
+ * so that changes do not continue to live only in D$, but to be
+ * replicated in I$ also (maybe we wrote the istructions)
+ */
+ uint32_t conf = 0;
+ int cached = 0;
+
+ if ((KSEGX(addr) == KSEG1) || ((addr >= 0xff200000) && (addr <= 0xff3fffff)))
+ return retval; /*Nothing to do*/
+
+ mips32_cp0_read(ejtag_info, &conf, 16, 0);
+
+ switch (KSEGX(addr)) {
+ case KUSEG:
+ cached = (conf & MIPS32_CONFIG0_KU_MASK) >> MIPS32_CONFIG0_KU_SHIFT;
+ break;
+ case KSEG0:
+ cached = (conf & MIPS32_CONFIG0_K0_MASK) >> MIPS32_CONFIG0_K0_SHIFT;
+ break;
+ case KSEG2:
+ case KSEG3:
+ cached = (conf & MIPS32_CONFIG0_K23_MASK) >> MIPS32_CONFIG0_K23_SHIFT;
+ break;
+ default:
+ /* what ? */
+ break;
+ }
+
+ /**
+ * Check cachablitiy bits coherency algorithm -
+ * is the region cacheable or uncached.
+ * If cacheable we have to synchronize the cache
+ */
+ if (cached == 0x3) {
+ uint32_t start_addr, end_addr;
+ uint32_t rel;
+
+ start_addr = addr;
+ end_addr = addr + count * size;
+
+ /** select cache synchronisation mechanism based on Architecture Release */
+ rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
+ switch (rel) {
+ case MIPS32_ARCH_REL1:
+ /* MIPS32/64 Release 1 - we must use cache instruction */
+ mips32_pracc_clean_invalidate_cache(ejtag_info, start_addr, end_addr);
+ break;
+ case MIPS32_ARCH_REL2:
+ /* MIPS32/64 Release 2 - we can use synci instruction */
+ mips32_pracc_sync_cache(ejtag_info, start_addr, end_addr);
+ break;
+ default:
+ /* what ? */
+ break;
+ }
+ }
+
+ return retval;
+}
+
+int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
+{
+ 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) */