⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 linux下的jtag仿真器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * target/arm7tdmi/memory.c: implements the ARM7TDMI target's memory read/write * 			     operations. * * Copyright (C) 2003, Rongkai zhan <zhanrk@163.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* $Id: memory.c,v 1.3 2004/10/17 13:54:32 zhanrk Exp $ */#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include "jtager.h"#include "jtag.h"#include "target.h"int arm7tdmi_memory_read8(u8 *buf, u32 address, u32 length){	int i, 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;	i = retval = 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 byte each time */	while (i < 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);				/* LDRB R1, [R0] = 1110 0101 1101 0000 0001 0000 0000 0000 */		sc1->writein[0] = 0xE5D01000;		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, [R1]" running at debug-speed		 * to read out the contents of register R1.		 */		jtag_select_scanchain(1);		jtag_write_ireg(JTAG_INTEST);		/* STR R1, [R1] = 1110 0101 1000 0001 0001 0000 0000 0000 */		sc1->writein[0] = 0xE5811000;		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);		arm7tdmi_exec_instruction(sc1->writein, sc1->readout);		buf[i] = (u8)(sc1->readout[0] & 0x000000FF);				i++;		addr++;	} /* end of while (i < length) */	/*	 * Finally, clear breakpt ...	 */	arm7tdmi_ice_clear_breakpt();	return 0;} /* end of arm7tdmi_memory_read8(...) */int arm7tdmi_memory_write8(u8 *buf, u32 address, u32 length){	int i, 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;	retval = 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;	/* write one byte each time */	while (i < 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);		/*		 * 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] = (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);				/* STRB R1, [R0] = 1110 0101 1100 0000 0001 0000 0000 0000 */		sc1->writein[0] = 0xE5C01000;		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++;	} /* end of while (i < length) */	/*	 * Finally, clear breakpt ...	 */	arm7tdmi_ice_clear_breakpt();	return 0;} /* end of arm7tdmi_memory_write8(...) *//* * NOTE: this function has very slow read speed. */int arm7tdmi_memory_read16(u16 *buf, u32 address, u32 length){	int i, 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 &= 0xFFFFFFFE; /* align address with half word boundary */	retval = 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 half-word each time */	while (i < 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);				/* LDRH R1, [R0] = 1110 0001 1101 0000 0001 0000 1011 0000 */		sc1->writein[0] = 0xE1D010B0;		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, [R1]" running at debug-speed		 * to read out the contents of register R1.		 */		jtag_select_scanchain(1);		jtag_write_ireg(JTAG_INTEST);		/* STR R1, [R1] = 1110 0101 1000 0001 0001 0000 0000 0000 */		sc1->writein[0] = 0xE5811000;		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);		arm7tdmi_exec_instruction(sc1->writein, sc1->readout);		buf[i] = (u16)(sc1->readout[0] & 0x0000FFFF);				i++;		addr += 2;	} /* end of while (i < length) */	/*	 * Finally, clear breakpt ...	 */	arm7tdmi_ice_clear_breakpt();	return 0;} /* end of arm7tdmi_read16(...) *//* * NOTE: this function has very slow write speed. */int arm7tdmi_memory_write16(u16 *buf, u32 address, u32 length){	int i, 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 &= 0xFFFFFFFE; /* align address with half word boundary */	retval = 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;	/* write one half-word each time */	while (i < 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);		/*		 * 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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -