📄 memory.c
字号:
* LDR R1, [R1] = 1110 0101 1001 0001 0001 0000 0000 0000 */ sc1->writein[0] = 0xE5911000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = 0; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* * 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] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = (u32)buf[i]; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* two NOPs are needed, and i don't know why? */ arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* NOP with bit33 set HIGH */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = SYSTEM_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* STRH R1, [R0] = 1110 0001 1100 0000 0001 0000 1011 0000 */ sc1->writein[0] = 0xE1C010B0; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM7TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM7TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. */ jtag_select_scanchain(1); jtag_write_ireg(JTAG_INTEST); i++; addr += 2; } /* end of while (i < length) */ /* * Finally, clear breakpt ... */ arm7tdmi_ice_clear_breakpt(); return 0;} /* end of arm7tdmi_write16(...) */int arm7tdmi_memory_read32(u32 *buf, u32 address, u32 length){ int i, lines, retval; u32 addr = address; scan_chain_t *sc1 = &arm7tdmi_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; arm7tdmi_ice_set_breakpt(); /* * 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; /* * 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 ARM7TDMI 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, PC+xx = 0xE59F0000 */ sc1->writein[0] = 0xE59F0000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = addr; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* two NOPs are needed, and i don't know why? */ arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* NOP with bit33 set HIGH */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = SYSTEM_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* LDMIA R0, {R1-R8}=1110 1000 1011 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE8B001FE; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM7TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM7TDMI 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_select_scanchain(1); jtag_write_ireg(JTAG_INTEST); /* STM R0, {R1-R8} = 1110 1000 1000 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE88001FE; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; /* NOP */ arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* in the next 8 cycles - read out R1-R8 */ sc1->writein[0] = ARM_NOP; /* NOP */ for (i = 0; i < 8; i++) { arm7tdmi_exec_instruction(sc1->writein, sc1->readout); if (((lines*8) + i) < length) buf[(lines*8) + i] = sc1->readout[0]; } lines++; addr += (4*8); }/* end of while(...) */ /* * Finally, clear breakpt ... */ arm7tdmi_ice_clear_breakpt(); return 0;} /* end of arm7tdmi_read32(...) */int arm7tdmi_memory_write32(u32 *buf, u32 address, u32 length){ int i, j, lines, remainder, retval; u32 addr = address; scan_chain_t *sc1 = &arm7tdmi_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; /* set a breakpoint */ arm7tdmi_ice_set_breakpt(); /* 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; /* write one memory line each time */ while (i < lines) { /* * Load R0 with the address to write. * LDR R0, PC+xx = 0xE59F0000 */ sc1->writein[0] = 0xE59F0000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = addr; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* * Clear R1 - R8 to zero. * If not doint this step, when i write even number into * R1-R8, i always read back wrong result from R0-R8. Damn it. * LDM R0, {R1-R8} = 1110 1000 1001 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE89001FE; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* in the next 8 cycles, we scan in the data to write */ for (j = 0; j < 8; j++) { sc1->writein[0] = 0; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); } /* the last cycle of LDM instruction */ sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* * 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] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* in the next 8 cycles, we scan in the data to write */ for (j = 0; j < 8; j++) { sc1->writein[0] = buf[i*8+j]; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); } /* the last cycle of LDM instruction */ sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* two NOPs are needed, and i don't know why? */ arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* NOP with bit33 set HIGH */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = SYSTEM_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* STMIA R0, {R1-R8}=1110 1000 1000 0000 0000 0001 1111 1110 */ sc1->writein[0] = 0xE88001FE; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM7TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM7TDMI core re-entered the debug state. * Before the debug session continues, we must load the * TAP controller with the INTEST instruction. */ jtag_select_scanchain(1); jtag_write_ireg(JTAG_INTEST); i++; addr += (4*8); } /* end of while(i < lines) */ /* write the remaining words */ i = 0; while (i < remainder) { /* * Load R0 with the address to write. * LDR R0, PC+xx = 0xE59F0000 */ sc1->writein[0] = 0xE59F0000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = addr; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* * Clear R1 to zero. If not doing this step, when i write * even number into R1, i always read back wrong result * from R1. Damn it. * LDR R1, [R1] = 1110 0101 1001 0001 0001 0000 0000 0000 */ sc1->writein[0] = 0xE5911000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = 0; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* * 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] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = buf[lines*8 + i]; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); sc1->writein[0] = ARM_NOP; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* two NOPs are needed, and i don't know why? */ arm7tdmi_exec_instruction(sc1->writein, sc1->readout); arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* NOP with bit33 set HIGH */ sc1->writein[0] = ARM_NOP; sc1->writein[1] = SYSTEM_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* STR R1, [R0] = 1110 0101 1000 0000 0001 0000 0000 0000 */ sc1->writein[0] = 0xE5801000; sc1->writein[1] = DEBUG_SPEED; arm7tdmi_exec_instruction(sc1->writein, sc1->readout); /* Write RESTART instruction into the TAP controller. * When the state machine enters the Run-Test/Idle state, * the ARM7TDMI core will revert back to system mode, * and it will resynchronize clock to MCLK. */ jtag_write_ireg(JTAG_RESTART); /* * Now, the ARM7TDMI 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_select_scanchain(1); jtag_write_ireg(JTAG_INTEST); i++; addr += 4; } /* end of while (i < remainder) */ /* * Finally, clear breakpt ... */ arm7tdmi_ice_clear_breakpt(); return 0;} /* end of arm7tdmi_write32(...) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -