This is an automated email from Gerrit.

"Walter Ji <walter...@oss.cipunited.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7865

-- gerrit

commit a9c9e8f621943c0045f3ad9213df6fd3a78abb0b
Author: Walter Ji <walter...@oss.cipunited.com>
Date:   Fri Aug 25 18:54:22 2023 +0800

    mips32: optimize pracc access
    
    Add SYNC and barrier instruction blocks for memory access safety.
    Rework mips32_pracc_read/write_regs function.
    
    Change-Id: Ib14112f37ff1f060b1633df73d671a6b09bb2178
    Signed-off-by: Walter Ji <walter...@oss.cipunited.com>

diff --git a/src/target/mips32.c b/src/target/mips32.c
index 5f3933f09c..755b958450 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -394,10 +394,9 @@ int mips32_save_context(struct target *target)
 
        /* get pointers to arch-specific information */
        struct mips32_common *mips32 = target_to_mips32(target);
-       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
 
        /* read core registers */
-       mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
+       mips32_pracc_read_regs(mips32);
 
        for (i = 0; i < MIPS32_NUM_REGS; i++) {
                if (!mips32->core_cache->reg_list[i].valid)
@@ -413,7 +412,6 @@ int mips32_restore_context(struct target *target)
 
        /* get pointers to arch-specific information */
        struct mips32_common *mips32 = target_to_mips32(target);
-       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
 
        for (i = 0; i < MIPS32_NUM_REGS; i++) {
                if (mips32->core_cache->reg_list[i].dirty)
@@ -421,7 +419,7 @@ int mips32_restore_context(struct target *target)
        }
 
        /* write core regs */
-       mips32_pracc_write_regs(ejtag_info, mips32->core_regs);
+       mips32_pracc_write_regs(mips32);
 
        return ERROR_OK;
 }
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index c4704b5a5d..617c293bf0 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -452,6 +452,7 @@ static int mips32_pracc_read_u32(struct mips_ejtag 
*ejtag_info, uint32_t addr, u
        pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR));     
/* $15 = MIPS32_PRACC_BASE_ADDR */
        pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16((addr + 0x8000)))); 
/* load  $8 with modified upper addr */
        pracc_add(&ctx, 0, MIPS32_LW(ctx.isa, 8, LOWER16(addr), 8));            
        /* lw $8, LOWER16(addr)($8) */
+       pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa));
        pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
                                MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15));   
/* sw $8,PRACC_OUT_OFFSET($15) */
        pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);                           
/* restore $8 */
@@ -508,6 +509,7 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, 
uint32_t addr, int size
                        else
                                pracc_add(&ctx, 0, MIPS32_LBU(ctx.isa, 8, 
LOWER16(addr), 9));
 
+                       pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa));
                        pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + i * 4,         
        /* store $8 at param out */
                                          MIPS32_SW(ctx.isa, 8, 
PRACC_OUT_OFFSET + i * 4, 15));
                        addr += size;
@@ -550,6 +552,7 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t 
*val, uint32_t cp0_r
        pracc_queue_init(&ctx);
 
        pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR));     
/* $15 = MIPS32_PRACC_BASE_ADDR */
+       pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa));
        pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, cp0_reg, cp0_sel));          
/* move cp0 reg / sel to $8 */
        pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
                                MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15));   
/* store $8 to pracc_out */
@@ -571,6 +574,7 @@ int mips32_cp0_write(struct mips_ejtag *ejtag_info, 
uint32_t val, uint32_t cp0_r
        pracc_add_li32(&ctx, 15, val, 0);                               /* Load 
val to $15 */
 
        pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, cp0_reg, cp0_sel));         
/* write $15 to cp0 reg / sel */
+       pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa));
        pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << 
ctx.isa)));          /* jump to start */
        pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));                    
/* restore $15 from DeSave */
 
@@ -818,88 +822,307 @@ int mips32_pracc_write_mem(struct mips_ejtag 
*ejtag_info, uint32_t addr, int siz
                        return ERROR_FAIL;
                }
                retval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, 
end_addr, cached, rel);
+       } else {
+               struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+
+               pracc_queue_init(&ctx);
+               pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa));
+               pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa));
+               pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) 
<< ctx.isa)));  /* jump to start */
+               pracc_add(&ctx, 0, MIPS32_NOP);
+               ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
+               if (ctx.retval != ERROR_OK) {
+                       LOG_ERROR("Unable to barrier");
+                       retval = ctx.retval;
+               }
+               pracc_queue_free(&ctx);
        }
 
        return retval;
 }
 
-int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
+int mips32_pracc_write_regs(struct mips32_common *mips32)
 {
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
        struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+       uint32_t *gprs = mips32->core_regs.gpr;
+       uint32_t *c0rs = mips32->core_regs.cp0;
+       bool status_fr = (c0rs[0] >> MIPS32_CP0_STATUS_FR_SHIFT) & 0x1;
+       bool status_cu1 = (c0rs[0] >> MIPS32_CP0_STATUS_CU1_SHIFT) & 0x1;
+
        pracc_queue_init(&ctx);
 
        uint32_t cp0_write_code[] = {
-               MIPS32_MTC0(ctx.isa, 1, 12, 0),                                 
/* move $1 to status */
-               MIPS32_MTLO(ctx.isa, 1),                                        
        /* move $1 to lo */
-               MIPS32_MTHI(ctx.isa, 1),                                        
        /* move $1 to hi */
-               MIPS32_MTC0(ctx.isa, 1, 8, 0),                                  
/* move $1 to badvaddr */
-               MIPS32_MTC0(ctx.isa, 1, 13, 0),                                 
/* move $1 to cause*/
-               MIPS32_MTC0(ctx.isa, 1, 24, 0),                                 
/* move $1 to depc (pc) */
+               MIPS32_MTC0(ctx.isa, 1, 12, 0),         /* move $1 to status */
+               MIPS32_MTLO(ctx.isa, 1),                /* move $1 to lo */
+               MIPS32_MTHI(ctx.isa, 1),                /* move $1 to hi */
+               MIPS32_MTC0(ctx.isa, 1, 8, 0),          /* move $1 to badvaddr 
*/
+               MIPS32_MTC0(ctx.isa, 1, 13, 0),         /* move $1 to cause*/
+               MIPS32_MTC0(ctx.isa, 1, 24, 0),         /* move $1 to depc (pc) 
*/
        };
 
-       /* load registers 2 to 31 with li32, optimize */
-       for (int i = 2; i < 32; i++)
-               pracc_add_li32(&ctx, i, regs[i], 1);
+       uint32_t cp0_write_data[] = {
+               /* status */
+               c0rs[0],
+               /* lo */
+               gprs[32],
+               /* hi */
+               gprs[33],
+               /* badvaddr */
+               c0rs[1],
+               /* cause */
+               c0rs[2],
+               /* depc (pc) */
+               c0rs[3],
+       };
 
+       /* write CP0 first because the user can request a change to 
status.{fr,cu1} */
        for (int i = 0; i != 6; i++) {
-               pracc_add_li32(&ctx, 1, regs[i + 32], 0);       /* load CPO 
value in $1 */
-               pracc_add(&ctx, 0, cp0_write_code[i]);                  /* 
write value from $1 to CPO register */
+               /* load CP0 value in $1 */
+               pracc_add_li32(&ctx, 1, cp0_write_data[i], 0);
+               /* write value from $1 to CP0 register */
+               pracc_add(&ctx, 0, cp0_write_code[i]);
+       }
+
+       pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa));
+
+       /* store FPRs */
+       if (mips32->fp_imp && status_cu1) {
+               uint64_t *fprs = mips32->core_regs.fpr;
+               if (status_fr) {
+                       for (int i = 0; i != MIPS32_REG_FP_COUNT; i++) {
+                               uint32_t fp_lo = fprs[i] & 0xffffffff;
+                               uint32_t fp_hi = (fprs[i] >> 32) & 0xffffffff;
+                               pracc_add_li32(&ctx, 2, fp_lo, 0);
+                               pracc_add_li32(&ctx, 3, fp_hi, 0);
+                               pracc_add(&ctx, 0, MIPS32_MTC1(ctx.isa, 2, i));
+                               pracc_add(&ctx, 0, MIPS32_MTHC1(ctx.isa, 3, i));
+                       }
+               } else {
+                       for (int i = 0; i != MIPS32_REG_FP_COUNT; i++) {
+                               uint32_t fp_lo = fprs[i] & 0xffffffff;
+                               pracc_add_li32(&ctx, 2, fp_lo, 0);
+                               pracc_add(&ctx, 0, MIPS32_MTC1(ctx.isa, 2, i));
+                       }
+               }
+
+               pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa));
        }
-       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));                    
        /* load $15 in DeSave */
-       pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, UPPER16((regs[1]))));         
/* load upper half word in $1 */
-       pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << 
ctx.isa)));          /* jump to start */
-       pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 1, 1, LOWER16((regs[1]))));      
/* load lower half word in $1 */
+
+       /* load registers 2 to 31 with li32, optimize */
+       for (int i = 2; i < 32; i++)
+               pracc_add_li32(&ctx, i, gprs[i], 1);
+
+       /* load $15 in DeSave */
+       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));
+       /* load upper half word in $1 */
+       pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, UPPER16((gprs[1]))));
+       /* jump to start */
+       pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << 
ctx.isa)));
+       /* load lower half word in $1 */
+       pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 1, 1, LOWER16((gprs[1]))));
 
        ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
 
-       ejtag_info->reg8 = regs[8];
-       ejtag_info->reg9 = regs[9];
+       ejtag_info->reg8 = gprs[8];
+       ejtag_info->reg9 = gprs[9];
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
 
-int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
+int mips32_pracc_read_regs(struct mips32_common *mips32)
 {
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
        struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+       struct mips32_core_regs *core_regs = &mips32->core_regs;
+       unsigned int offset_gpr = ((uint8_t *)&core_regs->gpr[0]) - (uint8_t 
*)core_regs;
+       unsigned int offset_fpr = ((uint8_t *)&core_regs->fpr[0]) - (uint8_t 
*)core_regs;
+       unsigned int offset_fpcr = ((uint8_t *)&core_regs->fpcr[0]) - (uint8_t 
*)core_regs;
+       unsigned int offset_cp0 = ((uint8_t *)&core_regs->cp0[0]) - (uint8_t 
*)core_regs;
+       bool status_cu1;
+       int step = 0;
+
+       /*
+        * This procedure has to be in 2 distinctive steps, because we can
+        * only know whether FP is enabled after reading CP0.
+        *
+        * Step 1: Read everything except CP1 stuff
+        * Step 2: Read CP1 stuff if FP is implemented
+        */
+
+begin_pracc:
        pracc_queue_init(&ctx);
 
+       uint32_t lohi_read_code[] = {
+               MIPS32_MFLO(ctx.isa, 8),        /* move lo to $8 */
+               MIPS32_MFHI(ctx.isa, 8),        /* move hi to $8 */
+       };
+
        uint32_t cp0_read_code[] = {
-               MIPS32_MFC0(ctx.isa, 8, 12, 0),                                 
/* move status to $8 */
-               MIPS32_MFLO(ctx.isa, 8),                                        
        /* move lo to $8 */
-               MIPS32_MFHI(ctx.isa, 8),                                        
        /* move hi to $8 */
-               MIPS32_MFC0(ctx.isa, 8, 8, 0),                                  
/* move badvaddr to $8 */
-               MIPS32_MFC0(ctx.isa, 8, 13, 0),                                 
/* move cause to $8 */
-               MIPS32_MFC0(ctx.isa, 8, 24, 0),                                 
/* move depc (pc) to $8 */
+               MIPS32_MFC0(ctx.isa, 8, 12, 0), /* move status to $8 */
+               MIPS32_MFC0(ctx.isa, 8, 8, 0),  /* move badvaddr to $8 */
+               MIPS32_MFC0(ctx.isa, 8, 13, 0), /* move cause to $8 */
+               MIPS32_MFC0(ctx.isa, 8, 24, 0), /* move depc (pc) to $8 */
        };
 
-       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 1, 31, 0));                     
        /* move $1 to COP0 DeSave */
-       pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, PRACC_UPPER_BASE_ADDR));      
/* $1 = MIP32_PRACC_BASE_ADDR */
+       /* move $1 to COP0 DeSave */
+       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 1, 31, 0));
+       /* $1 = MIP32_PRACC_BASE_ADDR */
+       pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, PRACC_UPPER_BASE_ADDR));
+
+       if (step == 0) {
+               /* store GPR's 2 to 31 */
+               for (int i = 2; i != 32; i++)
+                       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset_gpr + 
(i * 4),
+                                         MIPS32_SW(ctx.isa, i, 
PRACC_OUT_OFFSET + offset_gpr + (i * 4), 1));
+
+               /* store lo & hi */
+               for (int i = 0; i != 2; i++) {
+                       /* load COP0 needed registers to $8 */
+                       pracc_add(&ctx, 0, lohi_read_code[i]);
+                       /* store $8 at PARAM OUT */
+                       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i + 32) * 4,
+                                         MIPS32_SW(ctx.isa, 8, 
PRACC_OUT_OFFSET + (i + 32) * 4, 1));
+               }
 
-       for (int i = 2; i != 32; i++)                                   /* 
store GPR's 2 to 31 */
-               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i * 4),
-                                 MIPS32_SW(ctx.isa, i, PRACC_OUT_OFFSET + (i * 
4), 1));
+               /* store cp0 */
+               for (int i = 0; i != 4; i++) {
+                       size_t offset = offset_cp0 + (i * 4);
+
+                       /* load COP0 needed registers to $8 */
+                       pracc_add(&ctx, 0, cp0_read_code[i]);
+                       /* store $8 at PARAM OUT */
+                       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset,
+                                         MIPS32_SW(ctx.isa, 8, 
PRACC_OUT_OFFSET + offset, 1));
+               }
+       } else {
+               /* store FPRs if FP is implemented and enabled */
+               /* note: the check is in the end of this function */
+
+               /* FCSR */
+               pracc_add(&ctx, 0, MIPS32_CFC1(ctx.isa, 8, 31));
+               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset_fpcr,
+                                 MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + 
offset_fpcr, 1));
+
+               /* FIR */
+               pracc_add(&ctx, 0, MIPS32_CFC1(ctx.isa, 8, 0));
+               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset_fpcr + 4,
+                                 MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + 
offset_fpcr + 4, 1));
+
+               /* f0 to f31 */
+               if (mips32->fpu_in_64bit) {
+                       for (int i = 0; i != 32; i++) {
+                               size_t offset = offset_fpr + (i * 8);
+                               /* current pracc implementation (or EJTAG 
itself) only supports 32b access */
+                               /* so there is no way to use SDC1 */
+
+                               /* lower half */
+                               pracc_add(&ctx, 0, MIPS32_MFC1(ctx.isa, 8, i));
+                               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset,
+                                                 MIPS32_SW(ctx.isa, 8, 
PRACC_OUT_OFFSET + offset, 1));
+
+                               /* upper half */
+                               pracc_add(&ctx, 0, MIPS32_MFHC1(ctx.isa, 8, i));
+                               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset 
+ 4,
+                                                 MIPS32_SW(ctx.isa, 8, 
PRACC_OUT_OFFSET + offset + 4, 1));
+                       }
+               } else {
+                       for (int i = 0; i != 32; i++) {
+                               size_t offset = offset_fpr + (i * 8);
+                               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + offset,
+                                                 MIPS32_SWC1(ctx.isa, i, 
PRACC_OUT_OFFSET + offset, 1));
+                       }
+               }
 
-       for (int i = 0; i != 6; i++) {
-               pracc_add(&ctx, 0, cp0_read_code[i]);                           
/* load COP0 needed registers to $8 */
-               pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i + 32) * 4,          
        /* store $8 at PARAM OUT */
-                                 MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + (i + 
32) * 4, 1));
        }
-       pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 31, 0));                     
/* move DeSave to $8, reg1 value */
-       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + 4,                     /* 
store reg1 value from $8 to param out */
+
+       /* move DeSave to $8, reg1 value */
+       pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 31, 0));
+       /* store reg1 value from $8 to param out */
+       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + 4,
                          MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + 4, 1));
 
-       pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 1, 31, 0));             /* move 
COP0 DeSave to $1, restore reg1 */
-       pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << 
ctx.isa)));          /* jump to start */
-       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));                    
        /* load $15 in DeSave */
+       /* move COP0 DeSave to $1, restore reg1 */
+       pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 1, 31, 0));
+       /* jump to start */
+       pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << 
ctx.isa)));
+       /* load $15 in DeSave */
+       pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs, 1);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, (uint32_t 
*)&mips32->core_regs, 1);
 
-       ejtag_info->reg8 = regs[8];     /* reg8 is saved but not restored, next 
called function should restore it */
-       ejtag_info->reg9 = regs[9];
        pracc_queue_free(&ctx);
+
+       /* decide whether to launch the next step if we're in the first step */
+       if (step == 0) {
+               /* we only care if FP is actually impl'd */
+               if (mips32->fp_imp) {
+                       /* since we already read cp0 in the prev step */
+                       /* now we know what's in cp0.status */
+                       status_cu1 = (mips32->core_regs.cp0[0] >> 
MIPS32_CP0_STATUS_CU1_SHIFT) & 0x1;
+
+                       if (status_cu1) {
+                               /* yay let's rock */
+                               step = 1;
+                               goto begin_pracc;
+                       }
+               }
+       }
+
+       /* reg8 is saved but not restored, next called function should restore 
it */
+       ejtag_info->reg8 = mips32->core_regs.gpr[8];
+       ejtag_info->reg9 = mips32->core_regs.gpr[9];
+
        return ctx.retval;
 }
 
+int mips32_pracc_fastdata_xfer_synchronize_cache(struct mips_ejtag 
*ejtag_info, uint32_t addr, int size, int count)
+{
+       int retval = ERROR_OK;
+
+       if ((KSEGX(addr) == KSEG1) || ((addr >= 0xff200000) && (addr <= 
0xff3fffff))) // DESEG?
+               return retval; /*Nothing to do*/
+
+       int cached = 0;
+       uint32_t conf = 0;
+
+       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 cacheability bits coherency algorithm
+        * is the region cacheable or uncached.
+        * If cacheable we have to synchronize the cache
+        */
+       if (cached == 3 || cached == 0) {               /* Write back cache or 
write through cache */
+               uint32_t start_addr = addr;
+               uint32_t end_addr = addr + count * size;
+               uint32_t rel = (conf & MIPS32_CONFIG0_AR_MASK) >> 
MIPS32_CONFIG0_AR_SHIFT;
+               if (rel > 1) {
+                       LOG_DEBUG("Unknown release in cache code");
+                       return ERROR_FAIL;
+               }
+               retval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, 
end_addr, cached, rel);
+       }
+
+       return retval;
+}
+
 /* fastdata upload/download requires an initialized working area
  * to load the download code; it should not be called otherwise
  * fetch order from the fastdata area
@@ -920,13 +1143,17 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
                /* start of fastdata area in t0 */
                MIPS32_LUI(isa, 8, UPPER16(MIPS32_PRACC_FASTDATA_AREA)),
                MIPS32_ORI(isa, 8, 8, LOWER16(MIPS32_PRACC_FASTDATA_AREA)),
-               MIPS32_LW(isa, 9, 0, 8),                                        
        /* start addr in t1 */
-               MIPS32_LW(isa, 10, 0, 8),                                       
        /* end addr to t2 */
-                                       /* loop: */
+               MIPS32_LW(isa, 9, 0, 8),                                        
/* start addr in t1 */
+               MIPS32_SYNC(isa),                                               
/* barrier for ordering */
+               MIPS32_LW(isa, 10, 0, 8),                                       
/* end addr to t2 */
+               MIPS32_SYNC(isa),                                               
/* barrier for ordering */
+               /* loop: */
                write_t ? MIPS32_LW(isa, 11, 0, 8) : MIPS32_LW(isa, 11, 0, 9),  
/* from xfer area : from memory */
                write_t ? MIPS32_SW(isa, 11, 0, 9) : MIPS32_SW(isa, 11, 0, 8),  
/* to memory      : to xfer area */
 
-               MIPS32_BNE(isa, 10, 9, NEG16(3 << isa)),                        
/* bne $t2,t1,loop */
+               MIPS32_SYNC(isa),                                               
/* barrier for ordering */
+
+               MIPS32_BNE(isa, 10, 9, NEG16(4 << isa)),                        
/* bne $t2,t1,loop */
                MIPS32_ADDI(isa, 9, 9, 4),                                      
/* addi t1,t1,4 */
 
                MIPS32_LW(isa, 8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),
@@ -936,7 +1163,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
 
                MIPS32_LUI(isa, 15, UPPER16(MIPS32_PRACC_TEXT)),
                MIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_PRACC_TEXT) | isa),      
/* isa bit for JR instr */
-               MIPS32_JR(isa, 15),                                             
                /* jr start */
+               MIPS32_JRHB(isa, 15),                                           
                /* jr start */
                MIPS32_MFC0(isa, 15, 31, 0),                                    
/* move COP0 DeSave to $15 */
        };
 
@@ -956,7 +1183,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
        uint32_t jmp_code[] = {
                MIPS32_LUI(isa, 15, UPPER16(source->address)),                  
/* load addr of jump in $15 */
                MIPS32_ORI(isa, 15, 15, LOWER16(source->address) | isa),        
/* isa bit for JR instr */
-               MIPS32_JR(isa, 15),                                             
/* jump to ram program */
+               MIPS32_JRHB(isa, 15),                                           
/* jump to ram program */
                isa ? MIPS32_XORI(isa, 15, 15, 1) : MIPS32_NOP, /* drop isa 
bit, needed for LW/SW instructions */
        };
 
@@ -1020,5 +1247,5 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
        if (ejtag_info->pa_addr != MIPS32_PRACC_TEXT)
                LOG_ERROR("mini program did not return to start");
 
-       return retval;
+       return mips32_pracc_fastdata_xfer_synchronize_cache(ejtag_info, addr, 
4, count);
 }
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index 1b00768676..804de8ca84 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -51,6 +51,8 @@ struct pracc_queue_info {
        struct pa_list *pracc_list;     /* Code and store addresses at dmseg */
 };
 
+struct mips32_common;
+
 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_queue_free(struct pracc_queue_info *ctx);
@@ -64,8 +66,8 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info,
 int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct 
working_area *source,
                int write_t, uint32_t addr, int count, uint32_t *buf);
 
-int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
-int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
+int mips32_pracc_read_regs(struct mips32_common *mips32);
+int mips32_pracc_write_regs(struct mips32_common *mips32);
 
 /**
  * \b mips32_cp0_read

-- 

Reply via email to