📄 jtag.c
字号:
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : jtag.c
//* Object : Contains all functions related to JTAG
//*
//* 1.0 27/02/02 NL : Creation
//*----------------------------------------------------------------------------
#ifdef SEMIHOSTING
#include <stdio.h>
#endif
#include "parts/r40008/lib_r40008.h"
#include "targets/eb40a/eb40a.h"
#include "parts/r40008/reg_r40008.h"
#include "Flash_uploader.h"
#include "jtag.h"
#include "global.h"
//* Global Variables
extern u_int Current_Scan_Chain = -1;
u_int context[16]; //* used for saving context
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Select_Scan_Chain
//* Object : Select the Scan Chain
//* Input Parameters : sc
//* Output Parameters : none
//* Functions called : JTAG_Shift_ir, JTAG_Shift_dr_4_bits
//*----------------------------------------------------------------------------
void JTAG_Select_Scan_Chain(u_int sc){
//* Verify if the scan chain is already selected
if (Current_Scan_Chain == sc)
{
return;
}
else{
//* Shift SCAN_N instruction
JTAG_Shift_ir(SCAN_N, JTAG_NO_IDLE);
//* Shift the number of the scan chain
JTAG_Shift_dr_4_bits(sc, JTAG_NO_IDLE);
//* Shift INTEST instruction
JTAG_Shift_ir(INTEST, JTAG_NO_IDLE);
//* Update the global variable
Current_Scan_Chain = sc;
}
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Read_Debug_Status
//* Object : Read the Debug Status register of the ICEBreaker
//* Module
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : JTAG_Select_Scan_Chain, JTAG_Read_ICEBreaker
//*----------------------------------------------------------------------------
u_int JTAG_Read_Debug_Status(){
u_int value;
//* Select ICEBreaker Scan Chain
JTAG_Select_Scan_Chain(ICE_BREAKER);
//* Read the Debug Status register
JTAG_Read_Bkru(ICE_DBG_STS, &value);
return (value & ICE_DBG_STS_MASK);
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Test_Is_Breaked
//* Object : Test if the core is in debug mode
//* Input Parameters : value max of the watchdog
//* Output Parameters : none
//* Functions called : JTAG_Select_Scan_Chain, JTAG_Read_ICEBreaker
//*----------------------------------------------------------------------------
u_int JTAG_Test_Is_Breaked(u_int value){
u_int watchdog = 0;
//* Polling of the bits DBGACK and nMREQ
while ((watchdog < value) && ((JTAG_Read_Debug_Status() & READ_DEBUG_STATUS_MASK)
!= READ_DEBUG_STATUS_MASK))
{
watchdog++;
}
//* Test if the core is breaked
if (watchdog < value){
return TRUE;
}
else {
return FALSE;
}
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Execute
//* Object : Execute an instruction at debug speed
//* Input Parameters : instruction, data
//* Output Parameters : data
//* Functions called : JTAG_Select_Scan_Chain, JTAG_Step
//*----------------------------------------------------------------------------
void JTAG_Execute(u_int instruction, u_int *data){
//* Select the Debug Scan Chain
JTAG_Select_Scan_Chain(DEBUG);
//* Push the instruction in the pipe
JTAG_Step(instruction, data);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Nop
//* Object : Execute a nop instruction at debug speed
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : JTAG_Step
//*----------------------------------------------------------------------------
void JTAG_Nop(){
//* Select the Debug Scan Chain
JTAG_Select_Scan_Chain(DEBUG);
//* Push a nop in the pipe
JTAG_Step(NOP, NULL);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Nop_System_Speed
//* Object : Execute a nop instruction at system speed
//* Input Parameters : none
//* Output Parameters : none
//* Functions called : JTAG_Step_System_speed
//*----------------------------------------------------------------------------
void JTAG_Nop_System_Speed(){
//* Select the Debug Scan Chain
JTAG_Select_Scan_Chain(DEBUG);
//* Push a nop in the pipe with breakpoint bit set
JTAG_Step_System_Speed(NOP);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Read_Register
//* Object : Read a register
//* Input Parameters : index
//* Output Parameters : value
//* Functions called : JTAG_Nop, JTAG_Execute
//*----------------------------------------------------------------------------
void JTAG_Read_Register(u_char index, u_int *value){
//* Execute STR R[index], [R14]
JTAG_Execute(READ_REG | (index<<12), NULL);
JTAG_Nop();
JTAG_Nop();
//* Get the data
JTAG_Nop(); //* data is presented on falling edge of DCLK
//* Execute a nop to read the data
JTAG_Step(NOP, value);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Write_Register
//* Object : Write a value in a register
//* Input Parameters : index, value
//* Output Parameters : none
//* Functions called : JTAG_Nop, JTAG_Execute
//*----------------------------------------------------------------------------
void JTAG_Write_Register(u_char index, u_int value){
//* Execute LDR R[index], [R14]
JTAG_Execute(WRITE_REG | (index<<12), NULL);
JTAG_Nop();
JTAG_Nop();
//* Send the value
JTAG_Execute(value, NULL);
JTAG_Nop();
if (index == PC)
{
JTAG_Nop();
JTAG_Nop();
}
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Read_CPSR
//* Object : Read CPSR register
//* Input Parameters : *value
//* Output Parameters :
//* Functions called :
//*----------------------------------------------------------------------------
void JTAG_Read_CPSR(u_int *value){
u_int reg0;
//* Backup R0
JTAG_Read_Register(R0, ®0);
//* Execute MRS r0, cpsr
JTAG_Execute(READ_CPSR, NULL);
JTAG_Nop();
JTAG_Nop();
//* Read the result
JTAG_Read_Register(R0, value);
//* Restore R0
JTAG_Write_Register(R0, reg0);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Write_CPSR
//* Object : Write CPSR register
//* Input Parameters : *value
//* Output Parameters : none
//* Functions called :
//*----------------------------------------------------------------------------
void JTAG_Write_CPSR(u_short mode, IRQ_BIT irq, FIQ_BIT fiq, THUMB_BIT thumb){
u_int reg0, cpsr_value = 0;
//* Backup R0
JTAG_Read_Register(R0, ®0);
//* Create new cpsr value
cpsr_value = (irq<<7) | (fiq<<6) | (thumb<<5) | mode;
//* Store cpsr_value in R0
JTAG_Write_Register(R0, cpsr_value);
//* Execute MSR cpsr_cxsf, r0
JTAG_Execute(WRITE_CPSR, NULL);
JTAG_Nop();
JTAG_Nop();
//* Restore R0
JTAG_Write_Register(R0, reg0);
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Analyse_CPSR
//* Object : Analyse CPSR register
//* Input Parameters : value
//* Output Parameters : none
//* Functions called :
//*----------------------------------------------------------------------------
void JTAG_Analyse_CPSR(u_int value){
u_int I_Mask = 1<<7, F_Mask = 1<<6, T_Mask = 1<<5;
u_int Mode_Mask = 0x1F;
//* Mode
switch (value & Mode_Mask){
case 0x10 :
at91_print(&COM0,"User Mode\n\r");
break;
case 0x11 :
at91_print(&COM0,"FIQ Mode\n\r");
break;
case 0x12 :
at91_print(&COM0,"IRQ Mode\n\r");
break;
case 0x13 :
at91_print(&COM0,"Supervisor Mode\n\r");
break;
case 0x17 :
at91_print(&COM0,"Abort Mode\n\r");
break;
case 0x1B :
at91_print(&COM0,"Undef Mode\n\r");
break;
case 0x1F :
at91_print(&COM0,"System Mode\n\r");
break;
default : break;
}
if ((value & I_Mask) == I_Mask){
at91_print(&COM0,"IRQ disabled\n\r");
} else {
at91_print(&COM0,"IRQ enabled\n\r");
}
if ((value & F_Mask) == F_Mask){
at91_print(&COM0,"FIQ disabled\n\r");
} else {
at91_print(&COM0,"FIQ enabled\n\r");
}
if ((value & T_Mask) == T_Mask){
at91_print(&COM0,"Mode Thumb\n\r\n\r");
} else {
at91_print(&COM0,"Mode ARM\n\r\n\r");
}
return;
}
//*----------------------------------------------------------------------------
//* Function Name : JTAG_Read_Memory
//* Object : Read a value in memory
//* Input Parameters : address, halfword
//* Output Parameters : value
//* Functions called : JTAG_Nop, JTAG_Execute
//*----------------------------------------------------------------------------
void JTAG_Read_Memory(u_int address, u_int *value, u_short halfword, u_short bug){
u_int i;
u_int reg0, reg1;
//* Backup the value of R0 and R1
JTAG_Read_Register(0, ®0);
JTAG_Read_Register(1, ®1);
//* Load the address in R0
JTAG_Write_Register(0, address);
//*********************************************
//* Read the memory and store the result in R1
//*********************************************
//* Select the Debug Scan Chain
JTAG_Select_Scan_Chain(DEBUG);
//* Nop to be sure that the pipe is clean ???
JTAG_Nop();
//* Put the system speed flag for the next instruction to execute
JTAG_Nop_System_Speed();
if (halfword){
//* Push the LDR instruction
JTAG_Step(READ_MEM_HALFWORD, NULL); //* Execute ldr r1, [r0], #4
} else {
//* Push the LDR instruction
JTAG_Step(READ_MEM, NULL); //* Execute ldr r1, [r0], #4
}
//* Send the data on the data bus
JTAG_Nop();
//* Restart at system speed
JTAG_Shift_ir(RESTART, JTAG_NO_IDLE); //* Shift RESTART instruction
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -