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


/* 
 * ice.c:	implement the routes used to access the Embedded-ICE 
 *			logic registers via scan chain 2. 
 * 
 * Copyright (C) 2004, OPEN-JTAG, All rights reserved. 
 */ 
 
 
#include  
#include "../types.h" 
#include "../xjerr.h" 
#include "../tapctrl.h" 
#include "ice.h" 
#include "arm7tdmi.h" 
 
 
 
/* 
 * This array is used to map the ICE register address to  
 * the length of corresponding regisger. -1 indicates that  
 * the address is invalid. 
 */ 
static const int icereg_addr_map[32] =  
{ 
 ARM7TDMI_REGLEN_ICE_DBGCTRL, ARM7TDMI_REGLEN_ICE_DBGSTAT, ARM7TDMI_REGLEN_ICE_ABTSTAT, ARM7TDMI_REGLEN_ICE_INVALID, 
 ARM7TDMI_REGLEN_ICE_DCCCTRL, ARM7TDMI_REGLEN_ICE_DCCDATA, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, 
 ARM7TDMI_REGLEN_WP0_ADDRVAL, ARM7TDMI_REGLEN_WP0_ADDRMSK, ARM7TDMI_REGLEN_WP0_DATAVAL, ARM7TDMI_REGLEN_WP0_DATAMSK, 
 ARM7TDMI_REGLEN_WP0_CTRLVAL, ARM7TDMI_REGLEN_WP0_CTRLMSK, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, 
 ARM7TDMI_REGLEN_WP1_ADDRVAL, ARM7TDMI_REGLEN_WP1_ADDRMSK, ARM7TDMI_REGLEN_WP1_DATAVAL, ARM7TDMI_REGLEN_WP1_DATAMSK,			 
 ARM7TDMI_REGLEN_WP1_CTRLVAL, ARM7TDMI_REGLEN_WP1_CTRLMSK, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, 
 ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, 
 ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID, ARM7TDMI_REGLEN_ICE_INVALID 
}; 
 
 
/* 
 * int arm7tdmi_ice_write() - 
 *		This route is used to write a specific ICE register. 
 *		Please select scan chain 2 and put it into INTEST  
 *		state before calling this route. 
 * 
 *		@ice_reg:	the address of the target ICE register. 
 *		@ice_val:	the new value to be written 
 */ 
int arm7tdmi_ice_write(int ice_reg, u32 ice_val) 
{ 
	int status; 
	int reg_len; 
	u32 shift_in[2]; 
 
	//Check the validity of the ICE register 
	if(ice_reg < 0 || ice_reg > 32) 
		return XJERR_INVALID_ICEREG; 
	 
	reg_len = icereg_addr_map[ice_reg]; 
	if(reg_len == ARM7TDMI_REGLEN_ICE_INVALID) 
		return XJERR_INVALID_ICEREG; 
 
	//Scan chain 2 selected? 
	if(arm7tdmi_status.scanchain != 2) 
		return XJERR_SC2_NOT_SELECTED; 
 
	shift_in[0] = ice_val; 
	shift_in[1] = ice_reg | 0x20;	//Write flag 
 
	status = tapctrl_acs_dreg(ARM7TDMI_REGLEN_SC2, shift_in, NULL); 
	 
	return status; 
} 
 
 
/* 
 * int arm7tdmi_ice_read() - 
 *		This route is used to read a specific ICE register. 
 *		Please select scan chain 2 and put it into INTEST  
 *		state before calling this route. 
 * 
 *		@ice_reg:	the address of the target ICE register. 
 *		@ice_val:	a pointer of u32 used to return the read out value. 
 */ 
int arm7tdmi_ice_read(int ice_reg, u32 *ice_val) 
{ 
	int status; 
	int reg_len; 
	u32 shift_in[2]; 
	u32 shift_out[2]; 
 
	if(ice_val == NULL) 
		return XJERR_INVALID_PARAMATER; 
 
	//Check the validity of the ICE register 
	if(ice_reg < 0 || ice_reg > 32) 
		return XJERR_INVALID_ICEREG; 
	 
	reg_len = icereg_addr_map[ice_reg]; 
	if(reg_len == ARM7TDMI_REGLEN_ICE_INVALID) 
		return XJERR_INVALID_ICEREG; 
 
	//Scan chain 2 selected? 
	if(arm7tdmi_status.scanchain != 2) 
		return XJERR_SC2_NOT_SELECTED;	 
 
	shift_in[0] = 0; 
	shift_in[1] = ice_reg | 0x00;	//Read flag 
 
	/* 
	 * Need to use two cycle to read the ICE register. 
	 * The first cycle makes the vale of target ICE register appears 
	 * on scan chain2. The second cycle cpatures the data. 
	 */ 
	status = tapctrl_acs_dreg(ARM7TDMI_REGLEN_SC2, shift_in, shift_out); 
	status = tapctrl_acs_dreg(ARM7TDMI_REGLEN_SC2, shift_in, shift_out); 
 
	*ice_val = shift_out[0] & (0xffffffff >> (32 - reg_len)); 
 
	return status; 
}