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/+/7867

-- gerrit

commit 19cce959055f15701912cfa689cafe1b38ad8b93
Author: Walter Ji <walter...@oss.cipunited.com>
Date:   Fri Aug 25 17:54:47 2023 +0800

    target/mips32: add dsp access support
    
    Add access to dsp registers and a command for dsp related operations.
    
    Change-Id: I30aec0b9e4984896965edb1663f74216ad41101e
    Signed-off-by: Walter Ji <walter...@oss.cipunited.com>

diff --git a/src/target/mips32.c b/src/target/mips32.c
index 4a1338e40a..2fa3ce1e9b 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -1616,6 +1616,145 @@ COMMAND_HANDLER(mips32_handle_cp0_command)
        return ERROR_OK;
 }
 
+
+int mips32_pracc_read_dsp_regs(struct mips_ejtag *ejtag_info, uint32_t *val, 
uint32_t regs)
+{
+       int isa = 0;
+
+       struct pracc_queue_info ctx = {
+               .max_code = 48,
+               .ejtag_info = ejtag_info
+       };
+
+       uint32_t dsp_read_code[] = {
+               MIPS32_MFHI(isa, t0),           /* mfhi t0 ($ac0) OPCODE - 
0x00004010 */
+               MIPS32_DSP_MFHI(t0, 1), /* mfhi t0,$ac1 - OPCODE - 0x00204010 */
+               MIPS32_DSP_MFHI(t0, 2), /* mfhi t0,$ac2 - OPCODE - 0x00404010 */
+               MIPS32_DSP_MFHI(t0, 3), /* mfhi t0,$ac3 - OPCODE - 0x00604010*/
+               MIPS32_MFLO(isa, t0),           /* mflo t0 ($ac0) OPCODE - 
0x00004012 */
+               MIPS32_DSP_MFLO(t0, 1), /* mflo t0,$ac1 - OPCODE - 0x00204012 */
+               MIPS32_DSP_MFLO(t0, 2), /* mflo t0,$ac2 - OPCODE - 0x00404012 */
+               MIPS32_DSP_MFLO(t0, 3),         /* mflo t0,$ac3 - OPCODE - 
0x00604012 */
+               MIPS32_DSP_RDDSP(t0, 0x3F),     /* OPCODE - 0x7c3f44b8 */
+       };
+
+       /* Check status register to determine if dsp register access is enabled 
*/
+       /* Get status register so it can be restored later */
+
+       ctx.pracc_list = NULL;
+
+       /* Init context queue */
+       pracc_queue_init(&ctx);
+
+       if (ctx.retval != ERROR_OK)
+               goto exit;
+
+       /* Save Status Register */
+       /* move status to $9 (t1) 2*/
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 9, 12, 0));
+
+       /* Read it again in order to modify it */
+       /* move status to $0 (t0) 3*/
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 8, 12, 0));
+
+       /* Enable access to DSP registers by setting MX bit in status register 
*/
+       /* $15 = MIPS32_PRACC_STACK 4/5/6*/
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 15, UPPER16(MIPS32_DSP_ENABLE)));
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_DSP_ENABLE)));
+       pracc_add(&ctx, 0, MIPS32_ISA_OR(8, 8, 15));
+       /* Enable DSP - update status registers 7*/
+       pracc_add(&ctx, 0, MIPS32_MTC0(isa, 8, 12, 0));
+
+       /* move AC or Control to $8 (t0) 8*/
+       pracc_add(&ctx, 0, dsp_read_code[regs]);
+       /* Restore status registers to previous setting 9*/
+       pracc_add(&ctx, 0, MIPS32_MTC0(isa, 9, 12, 0));
+
+       /* $15 = MIPS32_PRACC_BASE_ADDR 1*/
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 15, PRACC_UPPER_BASE_ADDR));
+       /* store $8 to pracc_out 10*/
+       pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT, MIPS32_SW(isa, 8, 
PRACC_OUT_OFFSET, 15));
+       /* move COP0 DeSave to $15 11*/
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 15, 31, 0));
+       /* restore upper 16 of $8 12*/
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(ejtag_info->reg8)));
+       /* restore lower 16 of $8 13*/
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(ejtag_info->reg8)));
+       /* restore upper 16 of $9 14*/
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 9, UPPER16(ejtag_info->reg9)));
+       pracc_add(&ctx, 0, MIPS32_SYNC(isa));
+       /* jump to start 18*/
+       pracc_add(&ctx, 0, MIPS32_B(isa, NEG16(ctx.code_count + 1)));
+       /* restore lower 16 of $9 15*/
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 9, 9, LOWER16(ejtag_info->reg9)));
+
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1);
+exit:
+       pracc_queue_free(&ctx);
+       return ctx.retval;
+}
+
+int mips32_pracc_write_dsp_regs(struct mips_ejtag *ejtag_info, uint32_t val, 
uint32_t regs)
+{
+       int isa = 0;
+
+       struct pracc_queue_info ctx = {
+               .max_code = 48,
+               .ejtag_info = ejtag_info
+       };
+
+       uint32_t dsp_write_code[] = {
+               MIPS32_MTHI(isa, t0),           /* OPCODE - 0x01000011 */
+               MIPS32_DSP_MTHI(t0, 1),         /* OPCODE - 0x01000811 */
+               MIPS32_DSP_MTHI(t0, 2),         /* OPCODE - 0x01001011 */
+               MIPS32_DSP_MTHI(t0, 3),         /* OPCODE - 0x01001811 */
+               MIPS32_MTLO(isa, t0),           /* OPCODE - 0x01000013 */
+               MIPS32_DSP_MTLO(t0, 1), /* OPCODE - 0x01000813 */
+               MIPS32_DSP_MTLO(t0, 2),         /* OPCODE - 0x01001013 */
+               MIPS32_DSP_MTLO(t0, 3),         /* OPCODE - 0x01001813 */
+               MIPS32_DSP_WRDSP(t0, 0x1F),
+       };
+
+       /* Init context queue */
+       pracc_queue_init(&ctx);
+       if (ctx.retval != ERROR_OK)
+               goto exit;
+
+       /* Save Status Register */
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 9, 12, 0));                         
        /* move status to $9 (t1) */
+
+       /* Read it again in order to modify it */
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 8, 12, 0));                         
        /* move status to $0 (t0) */
+
+       /* Enable access to DSP registers by setting MX bit in status register 
*/
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 15, UPPER16(MIPS32_DSP_ENABLE)));    
        /* $15 = MIPS32_PRACC_STACK */
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_DSP_ENABLE)));
+       pracc_add(&ctx, 0, MIPS32_ISA_OR(8, 8, 15));
+       pracc_add(&ctx, 0, MIPS32_MTC0(isa, 8, 12, 0));                         
        /* Enable DSP - update status registers */
+
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(val)));                   
/* Load val to $8 (t0) */
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(val)));
+
+       pracc_add(&ctx, 0, dsp_write_code[regs]);                               
         /* move AC or Control to $8 (t0) */
+
+       pracc_add(&ctx, 0, MIPS32_NOP);                                         
                /* nop */
+       pracc_add(&ctx, 0, MIPS32_MTC0(isa, 9, 12, 0));                         
        /* Restore status registers to previous setting */
+       pracc_add(&ctx, 0, MIPS32_NOP);                                         
                /* nop */
+
+       pracc_add(&ctx, 0, MIPS32_MFC0(isa, 15, 31, 0));                        
                                /* move COP0 DeSave to $15 */
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 8, UPPER16(ejtag_info->reg8)));      
        /* restore upper 16 of $8 */
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 8, 8, LOWER16(ejtag_info->reg8)));   
/* restore lower 16 of $8 */
+
+       pracc_add(&ctx, 0, MIPS32_LUI(isa, 9, UPPER16(ejtag_info->reg9)));      
        /* restore upper 16 of $9 */
+
+       pracc_add(&ctx, 0, MIPS32_B(isa, NEG16(ctx.code_count + 1)));           
/* jump to start */
+       pracc_add(&ctx, 0, MIPS32_ORI(isa, 9, 9, LOWER16(ejtag_info->reg9)));   
/* restore lower 16 of $9 */
+
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
+exit:
+       pracc_queue_free(&ctx);
+       return ctx.retval;
+}
 COMMAND_HANDLER(mips32_handle_cpuinfo_command)
 {
        int retval;
@@ -2257,6 +2396,84 @@ COMMAND_HANDLER(mips32_handle_cpuinfo_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(mips32_handle_dsp_command)
+{
+       int retval;
+       struct target *target = get_current_target(CMD_CTX);
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+       retval = mips32_verify_pointer(CMD, mips32);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (target->state != TARGET_HALTED) {
+               command_print(CMD, "target must be stopped for \"%s\" command", 
CMD_NAME);
+               return ERROR_OK;
+       }
+
+       /* Check for too many command arg.s */
+       if (CMD_ARGC >= 3)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       /* Check if DSP access supported or not */
+       if (!mips32->dsp_imp) {
+               /* Issue Error Message */
+               command_print(CMD, "DSP not implemented by this processor");
+               return ERROR_OK;
+       }
+
+       /* two or more argument, access a single register/select (write if 
third argument is given) */
+       if (CMD_ARGC < 2) {
+               uint32_t value;
+
+               if (CMD_ARGC == 0) {
+                       value = 0;
+                       for (int i = 0; i < MIPS32NUMDSPREGS; i++) {
+                               retval = mips32_pracc_read_dsp_regs(ejtag_info, 
&value, i);
+                               if (retval != ERROR_OK) {
+                                       command_print(CMD, "couldn't access reg 
%s", mips32_dsp_regs[i].name);
+                                       return retval;
+                               }
+                               command_print(CMD, "%*s: 0x%8.8x", 7, 
mips32_dsp_regs[i].name, value);
+                       }
+               } else {
+                       for (int i = 0; i < MIPS32NUMDSPREGS; i++) {
+                               /* find register name */
+                               if (strcmp(mips32_dsp_regs[i].name, 
CMD_ARGV[0]) == 0) {
+                                       retval = 
mips32_pracc_read_dsp_regs(ejtag_info, &value, i);
+                                       command_print(CMD, "0x%8.8x", value);
+                                       return retval;
+                               }
+                       }
+
+                       LOG_ERROR("BUG: register '%s' not found", CMD_ARGV[0]);
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+       } else {
+               if (CMD_ARGC == 2) {
+                       uint32_t value;
+                       int tmp = *CMD_ARGV[0];
+
+                       if (isdigit(tmp) == false) {
+                               for (int i = 0; i < MIPS32NUMDSPREGS; i++) {
+                                       /* find register name */
+                                       if (strcmp(mips32_dsp_regs[i].name, 
CMD_ARGV[0]) == 0) {
+                                               COMMAND_PARSE_NUMBER(u32, 
CMD_ARGV[1], value);
+                                               retval = 
mips32_pracc_write_dsp_regs(ejtag_info, value, i);
+                                               return retval;
+                                       }
+                               }
+
+                               LOG_ERROR("BUG: register '%s' not found", 
CMD_ARGV[0]);
+                               return ERROR_COMMAND_SYNTAX_ERROR;
+                       }
+               }
+       }
+
+       return ERROR_OK;
+}
+
 
 extern void ejtag_main_print_imp(struct mips_ejtag *ejtag_info);
 extern int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info);
@@ -2359,6 +2576,14 @@ static const struct command_registration 
mips32_exec_command_handlers[] = {
                .help = "cpuinfo displays information for the current CPU 
core.",
                .usage = "",
        },
+       {
+               .name = "dsp",
+               .handler = mips32_handle_dsp_command,
+               .mode = COMMAND_EXEC,
+               .help = "display or set DSP register; "
+                       "with no arguments, displays all registers and their 
values",
+               .usage = "[register_name] [value]]",
+       },
        {
                .name = "scan_delay",
                .handler = mips32_handle_scan_delay_command,

-- 

Reply via email to