www.pudn.com > jtag_src.rar > memory.c


/* 
 * system.c:	implement the routes used to access memory under 
 *				DEBUG state. 
 * 
 * Copyright (C) 2004, OPEN-JTAG, All rights reserved. 
 */ 
 
#include  
#include "../types.h" 
#include "../xjerr.h" 
#include "../tapctrl.h" 
#include "arm7tdmi.h" 
 
/* 
 * To meet the dynamic timing requirements of the memory system, any attempt to  
 * access system state must occur synchronously to it. The ARM7TDMI core must  
 * be forced to synchronize back to MCLK. This is controlled by bit 33 (BREAKPT) 
 * of scan chain 1.  
 * 
 * After a system-speed instruction has been scanned into the data bus and  
 * clocked into the pipeline, the RESTART instruction must be loaded into the TAP 
 * controller. This causes the ARM7TDMI core to behave as follows: 
 *	1. The ARM7TDMI core automatically synchronizes back to MCLK; 
 *	2. It executes the instruction at system speed; 
 *	3. It re-enters debug state. 
 */ 
 
 
 
 
/* 
 * arm7tdmi_mem_rd8() -  
 *		used to read memory at 8-bit width 
 * 
 *		@addr: address of memory to be read from 
 *		@buf:  buf used to store the content read from memory 
 *		@len:  lenngth in terms of 8-bit byte to be read 
 */ 
int arm7tdmi_mem_rd8(u32 addr, u8 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
 
	//Read memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address to be read to RO 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//LDRB R1, [R0] = 0xE5D01000 
		shift_in[0] = 0xE5D01000;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STRB R1, [R1] = 0xE5C11000 
		shift_in[0] = 0xE5C11000; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//NOP x 3 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//Update buffer and address 
		*buf = (u8)shift_out[0]; 
		buf += 1; 
		addr += 1; 
 
	} 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
} 
 
 
/* 
 * arm7tdmi_mem_wri8() -  
 *		used to wri memory at 8-bit width 
 * 
 *		@addr: destination address of memory to be written 
 *		@buf:  point to the content to be written 
 *		@len:  lenngth in terms of 8-bit byte to be written 
 */ 
int arm7tdmi_mem_wri8(u32 addr, const u8 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
	 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
 
	//Write memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address into R0 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//put the new value into R1 
		arm7tdmi_core_wri_reg(ARM7TDMI_R1, *buf); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STRB R1, [R0] = 0xE5C01000 
		shift_in[0] = 0xE5C01000;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		 
		//Update address and buffer 
		addr += 1; 
		buf += 1; 
	} 
 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
} 
 
 
/* 
 * arm7tdmi_mem_rd16() -  
 *		used to read memory at 16-bit width 
 * 
 *		@addr: address of memory to be read from 
 *		@buf:  buf used to store the content read from memory 
 *		@len:  lenngth in terms of 16-bit byte to be read 
 */ 
int arm7tdmi_mem_rd16(u32 addr, u16 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	/*  
	 * Shape the address to make sure that the least significant  
	 * 1 bit of addr is zero. 
	 */ 
	addr &= 0xFFFFFFFE; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
	//Read memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address to be read to RO 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//LDRH R1, [R0] = 0xE1D010B0 
		shift_in[0] = 0xE1D010B0;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STRH R1, [R1] = 0xE1C110B0 
		shift_in[0] = 0xE1C110B0; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//NOP x 3 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//Update buffer and address 
		*buf = (u16)shift_out[0]; 
		buf += 1; 
		addr += 2; 
	} 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
} 
 
 
/* 
 * arm7tdmi_mem_wri16() -  
 *		used to wri memory at 16-bit width 
 * 
 *		@addr: destination address of memory to be written 
 *		@buf:  point to the content to be written 
 *		@len:  lenngth in terms of 16-bit byte to be written 
 */ 
int arm7tdmi_mem_wri16(u32 addr, const u16 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	/*  
	 * Shape the address to make sure that the least significant  
	 * 1 bit of addr is zero. 
	 */ 
	addr &= 0xFFFFFFFE; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
 
	//Write memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address into R0 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//put the new value into R1 
		arm7tdmi_core_wri_reg(ARM7TDMI_R1, *buf); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STRH R1, [R0] = 0xE1C010B0 
		shift_in[0] = 0xE1C010B0;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		 
		//Update address and buffer 
		addr += 2; 
		buf += 1; 
	} 
 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
} 
 
 
/* 
 * arm7tdmi_mem_rd32() -  
 *		used to read memory at 32-bit width 
 * 
 *		@addr: address of memory to be read from 
 *		@buf:  buf used to store the content read from memory 
 *		@len:  lenngth in terms of 32-bit byte to be read 
 */ 
int arm7tdmi_mem_rd32(u32 addr, u32 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	/*  
	 * Shape the address to make sure that the least significant  
	 * 2 bits of addr are zero. 
	 */ 
	addr &= 0xFFFFFFFC; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
	//Read memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address to be read to RO 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//LDR R1, [R0] = 0xE5901000 
		shift_in[0] = 0xE5901000;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STR R1, [R1] = 0xE5811000 
		shift_in[0] = 0xE5811000; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//NOP x 3 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//Update buffer and address 
		*buf = shift_out[0]; 
		buf += 1; 
		addr += 4; 
	} 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
} 
 
 
/* 
 * arm7tdmi_mem_wri32() -  
 *		used to wri memory at 32-bit width 
 * 
 *		@addr: destination address of memory to be written 
 *		@buf:  point to the content to be written 
 *		@len:  lenngth in terms of 32-bit byte to be written 
 */ 
int arm7tdmi_mem_wri32(u32 addr, const u32 *buf, int len) 
{ 
	int status; 
	int counter; 
	u32 r0, r1; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(buf == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//In DEBUG state? 
	if(arm7tdmi_status.state != ARM7TDMI_DEBUG_STATE) 
		return XJERR_TARGET_RUNNING; 
	 
	//Select scan chain 1 
	status = arm7tdmi_connect_scanchain(1); 
	if(status != XJ_OK) 
		return status; 
 
	/*  
	 * Shape the address to make sure that the least significant  
	 * 2 bits of addr are zero. 
	 */ 
	addr &= 0xFFFFFFFC; 
 
	//Backup R0 & R1 first 
	arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0); 
	arm7tdmi_core_rd_reg(ARM7TDMI_R1, &r1); 
 
 
	//Write memory ... 
	for(counter = 0; counter < len; counter++){ 
		//put the address into R0 
		arm7tdmi_core_wri_reg(ARM7TDMI_R0, addr); 
 
		//put the new value into R1 
		arm7tdmi_core_wri_reg(ARM7TDMI_R1, *buf); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		/*  
		 * Set bit 33 of scan chain 1, next instruct  
		 * will be executed at system speed. 
		 */ 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_SYSTEM_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		//STR R1, [R0] = 0xE5801000 
		shift_in[0] = 0xE5801000;				 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
 
		tapctrl_acs_ireg(JTAG_BYPASS); 
		tapctrl_acs_ireg(JTAG_RESTART); 
		tapctrl_acs_ireg(JTAG_INTEST); 
 
		//NOP 
		shift_in[0] = ARM7TDMI_NOP; 
		shift_in[1] = ARM7TDMI_DEBUG_SPEED; 
		arm7tdmi_acs_sc1(shift_in, shift_out); 
		 
		//Update address and buffer 
		addr += 4; 
		buf += 1; 
	} 
 
 
	//Restore R0 & R1 before exit 
	arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0); 
	arm7tdmi_core_wri_reg(ARM7TDMI_R1, r1); 
 
	return XJ_OK; 
}