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, --