📄 memory.c
字号:
return -ERR_INVALID_PARAM; else if (target->status == TARGET_STATUS_RUNNING) return -ERR_TARGET_IS_RUNNING; else if (target->mode == TARGET_MODE_THUMB) return -ERR_TARGET_IN_THUMB_MODE; addr &= 0xFFFFFFFE; /* align address with half word boundary */ retval = i = 0; /* * Select scan chain 1, and use INTEST instruction to make scan * chain 1 into the internal test mode. */ retval = jtag_select_scanchain(1); if (retval) return retval; retval = jtag_write_ireg(JTAG_INTEST); if (retval) return retval; /* write one half-word each time */ while (i < length) { /* * Zero R0 * If not doing this step, things are wrong. I don't know why? */ sc1->writein[0] = 0xE5900000; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* scan in the address */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* * Load R0 with the address. * LDR R0, [R0] = 0xE5900000 */ sc1->writein[0] = 0xE5900000; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* scan in the address */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = addr; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* * Zero R1 */ sc1->writein[0] = 0xE5911000; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* * Load R1 with the data to write. * LDR R1, [R1] = 1110 0101 1001 0001 0001 0000 0000 0000 */ sc1->writein[0] = 0xE5911000; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = (u32)buf[i]; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* STRH R1, [R0] = 1110 0001 1100 0000 0001 0000 1011 0000 */ sc1->writein[0] = 0xE1C010B0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, SYSTEM_SPEED); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM9TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM9TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. */ jtag_write_ireg(JTAG_INTEST); i++; addr += 2; } /* end of while (i < length) */ return 0;} /* end of arm9tdmi_write16(...) */int arm9tdmi_memory_read32(u32 *buf, u32 address, u32 length){ int i, lines, retval; u32 addr = address; scan_chain_t *sc1 = &arm9tdmi_target.sc[1]; if ((buf == NULL) || (length == 0)) return -ERR_INVALID_PARAM; else if (target->status == TARGET_STATUS_RUNNING) return -ERR_TARGET_IS_RUNNING; else if (target->mode == TARGET_MODE_THUMB) return -ERR_TARGET_IN_THUMB_MODE; addr &= 0xFFFFFFFC; /* align address with word boundary */ lines = i = 0; /* * Select scan chain 1, and use INTEST instruction to make scan * chain 1 into the internal test mode. */ retval = jtag_select_scanchain(1); if (retval) return retval; retval = jtag_write_ireg(JTAG_INTEST); if (retval) return retval; arm9tdmi_r0_write(0); /* Zero R0 */ /* * Read one memory line (8 words) each time ... * * We use the instruction "LDMIA R0!, {R1-R8}", which is running at * system-speed, to read a memory line. To make the instruction * LDMIA run at system-speed, we insert a NOP with BREAKPT bit * set HIGH, it will make the ARM9TDMI core resynchronize back to * MCLK, and make LDMIA instruction executed at system-speed. */ while ((lines * 8) < length) { /* * Load R0 with the address to read. * LDR R0, [R0] = 0xE5900000 */ sc1->writein[0] = 0xE5900000; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* scan in the address */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = addr; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* LDMIA R0, {R1-R8}=1110 1000 1011 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE8B001FE; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, SYSTEM_SPEED); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM9TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM9TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. We can use * the instruction "STM R9, {R1-R8}" running at debug-speed * to read out the contents of registers R1-R8. */ jtag_write_ireg(JTAG_INTEST); /* STMIA R0, {R1-R8} = 1110 1000 1000 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE88001FE; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; /* NOP */ arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* in the next 8 cycles - read out R1-R8 */ sc1->writein[0] = ARM_NOP; /* NOP */ for (i = 0; i < 8; i++) { arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); if (((lines*8) + i) < length) buf[(lines*8) + i] = sc1->readout[0]; } lines++; addr += (4*8); }/* end of while(...) */ return 0;} /* end of arm9tdmi_read32(...) */int arm9tdmi_memory_write32(u32 *buf, u32 address, u32 length){ int i, j, lines, remainder, retval; u32 addr = address; scan_chain_t *sc1 = &arm9tdmi_target.sc[1]; if ((buf == NULL) || (length == 0)) return -ERR_INVALID_PARAM; else if (target->status == TARGET_STATUS_RUNNING) return -ERR_TARGET_IS_RUNNING; else if (target->mode == TARGET_MODE_THUMB) return -ERR_TARGET_IN_THUMB_MODE; /* select scan chain 1, and use INTEST instruction */ retval = jtag_select_scanchain(1); if (retval) return retval; retval = jtag_write_ireg(JTAG_INTEST); if (retval) return retval; addr &= 0xFFFFFFFC; /* align address with word boundary */ lines = length/8; /* 8 words per memory line */ remainder = length%8; i = j = 0; arm9tdmi_r0_write(addr); /* Load R0 with the address to write */ /* write one memory line each time */ while (i < lines) { /* * Zero R1 - R8 */ sc1->writein[0] = 0xE89001FE; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* in the next 8 cycles, we scan in the data to write */ sc1->writein[0] = ARM_NOP; for (j = 0; j < 8; j++) { sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); } /* the last cycle of LDM instruction */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* * Load R1 - R8 with the data to write. * LDM R0, {R1-R8} = 1110 1000 1001 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE89001FE; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* in the next 8 cycles, we scan in the data to write */ sc1->writein[0] = ARM_NOP; for (j = 0; j < 8; j++) { sc1->writein[1] = buf[i*8+j]; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); } /* the last cycle of LDM instruction */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* STMIA R0!, {R1-R8}=1110 1000 1010 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE8A001FE; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, SYSTEM_SPEED); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM9TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM9TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. */ jtag_write_ireg(JTAG_INTEST); i++; addr += (4*8); } /* end of while(i < lines) */ /* write the remaining words */ i = 0; while (i < remainder) { /* * Zero R1 */ sc1->writein[0] = 0xE5911000; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* scan in data */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* * Load R1 with the data to write. * LDR R1, [R1] = 1110 0101 1001 0001 0001 0000 0000 0000 */ sc1->writein[0] = 0xE5911000; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* scan in data */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = buf[lines*8 + i]; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; sc1->writein[1] = 0; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); /* STR R1, [R0], #4 = 1110 0100 1000 0000 0001 0000 0000 0100 */ sc1->writein[0] = 0xE4801004; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, DEBUG_SPEED); sc1->writein[0] = ARM_NOP; arm9tdmi_exec_instruction(sc1->writein, sc1->readout, SYSTEM_SPEED); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM9TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM9TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. We can use * the instruction "STR R1, [R2]" running at debug-speed to * read out the contents of registers R1-R8. */ jtag_write_ireg(JTAG_INTEST); i++; addr += 4; } /* end of while (i < remainder) */ return 0;} /* end of arm9tdmi_memory_write32(...) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -