?? arm7tdmi.c
字號:
* It is for later use to return from the DEBUG state back to
* the SYSTEM state.
*
* Please modify this function carefully.
*
* @pc: used to return the value of PC which indicates the next
* instruction to be execute on exit from DEBUG state.
*/
int arm7tdmi_check_dbgstat(u32 *pc)
{
int status;
u32 r0;
u32 dbgstat;
u32 shift_in[2];
u32 shift_out[2];
if(pc == NULL)
return XJERR_INVALID_PARAMATER;
//In DEBUG state?
if(arm7tdmi_status.state == ARM7TDMI_DEBUG_STATE)
return XJERR_TARGET_HALTED;
//Select scan chain 2
status = arm7tdmi_connect_scanchain(2);
if(status != XJ_OK)
return status;
//Check DEBUG status register
arm7tdmi_ice_read(ARM7TDMI_ICE_DBGSTAT, &dbgstat);
if(dbgstat & 0x1){
arm7tdmi_status.state = ARM7TDMI_DEBUG_STATE;
if (dbgstat & 0x10)
arm7tdmi_status.from = ARM7TDMI_FROM_THUMB;
else
arm7tdmi_status.from = ARM7TDMI_FROM_ARM;
}else
return XJERR_TARGET_RUNNING;
/*
* Try to obtain the value of PC when entering DEBUG state. The obtained
* value of PC indicates the next instruction to be executed on exit from
* DEBUG state.
*/
//Select scan chain 1
status = arm7tdmi_connect_scanchain(1);
if(status != XJ_OK)
return status;
if(arm7tdmi_status.from == ARM7TDMI_FROM_ARM){ //Enter DEBUG from ARM state
//Step 1 - Read R0
//STR R0, [R0] = 0xE5800000
shift_in[0] = 0xE5800000; //Instruction 1
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
/*
* After the ARM7TDMI core has entered debug state from breakpt/watchpt,
* the first time the 33rd bit is captured and scanned out, its value
* tells the debugger if the core entered debug state due to a breakpoint
* (bit 33 clear) or a watchpoint (bit 33 set).
*/
if(shift_out[1] & 0x1)
arm7tdmi_status.by = ARM7TDMI_BY_WATCHPT;
else
arm7tdmi_status.by = ARM7TDMI_BY_BREAKPT;
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruction 2
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruction 3
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
r0 = shift_out[0];
//Step 2 - Move PC to R0
//MOV R0, PC = 0xE1A0000F
shift_in[0] = 0xE1A0000F; //Instruction 4
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Step 3 - Read the value of PC from R0
//STR R0, [R0] = 0xE5800000
shift_in[0] = 0xE5800000;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
*pc = shift_out[0];
/*
* Entry into DEBUG state from a breakpoint/watchpoint advances the
* PC by four addresses. Each instruction executed in DEBUG state
* advances the PC by one address.
*
* To move the value of PC to R0, 4 instructions have been executed in D
* EBUG state. So, the value of PC which indicates the next instruction
* should be executed on exit from DEBUG state is
* pc - 4 x (4 + 4)
*/
*pc -= 32;
}else{ //Enter DEBUG from THUMB state
//Step 1 - Read R0
//STR R0, [R0] = 0x60006000
shift_in[0] = 0x60006000; //Instruction 1
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
/*
* After the ARM7TDMI core has entered debug state from breakpt/watchpt,
* the first time the 33rd bit is captured and scanned out, its value
* tells the debugger if the core entered debug state due to a breakpoint
* (bit 33 clear) or a watchpoint (bit 33 set).
*/
if(shift_out[1] & 0x1)
arm7tdmi_status.by = ARM7TDMI_BY_WATCHPT;
else
arm7tdmi_status.by = ARM7TDMI_BY_BREAKPT;
//NOP
shift_in[0] = 0x1C001C00; //Instruction 2
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00; //Instruction 3
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//R0
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
r0 = shift_out[0];
//Step 2 - Move PC to R0
//MOV R0, PC = 0x46784678
shift_in[0] = 0x46784678; //Instruction 4
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Step 3 - Read the value of PC from R0
//STR R0, [R0] = 0x60006000
shift_in[0] = 0x60006000;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
*pc = shift_out[0];
/*
* Entry into DEBUG state from a breakpoint/watchpoint advances the
* PC by four addresses. Each instruction executed in DEBUG state
* advances the PC by one address.
*
* To move the value of PC to R0, 4 instructions have been executed in D
* EBUG state. So, the value of PC which indicates the next instruction
* should be executed on exit from DEBUG state is
* pc - 2 x (4 + 4)
*/
*pc -= 16;
//Step4 - Switch from THUMB state to ARM state
/*
* When enter DEBUG state, we make ARM7TDMI enter ARM state before any
* further debug is performed. When leave from DEBUG state, we make
* ARM7TDMI return to THUMB state before the normal operation is resumed.
*/
//BX PC = 0x47784778
shift_in[0] = 0x47784778;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = 0x1C001C00;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
}
//LastStep - Restore R0
arm7tdmi_core_wri_reg(ARM7TDMI_R0, r0);
return XJ_OK;
}
/*
* arm7tdmi_exit_dbgstat() -
* This route is used to exit from the DEBUG state and return to the
* normal SYSTEM state. The input pc indicates the next instruction
* to be exectued on exit from DEBUG state. After some operations in
* the DEBUG state, this route can be used to exit from the DEBUG state
* and resume the execution of program under debug.
*
* Please modify this function carefully.
*
* @pc: the value of pc which indicates the next instruction to
* be executed on exit from DEBUG state.
*/
int arm7tdmi_exit_dbgstat(u32 pc)
{
int status;
u32 r0;
u32 shift_in[2];
u32 shift_out[2];
//In SYSTEM state?
if(arm7tdmi_status.state == ARM7TDMI_SYSTEM_STATE)
return XJ_OK;
//Clear the DEBUGRQ flag in DBGCTRL register
status = arm7tdmi_connect_scanchain(2);
if(status != XJ_OK)
return status;
status = arm7tdmi_ice_write(ARM7TDMI_ICE_DBGCTRL, 0x0);
if(status != XJ_OK)
return status;
//Select scan chain 1
status = arm7tdmi_connect_scanchain(1);
if(status != XJ_OK)
return status;
if(arm7tdmi_status.from == ARM7TDMI_FROM_ARM){ //Enter DEBUG from ARM state
//Step 1 - Read R0 & Write the new value of PC to R0
pc &= 0xFFFFFFFC; //Align
status = arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0);
status = arm7tdmi_core_wri_reg(ARM7TDMI_R0, pc);
//Step 2 - Move R0 to PC
//MOV PC, R0 = 0xE1A0F000
shift_in[0] = 0xE1A0F000;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 1
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 2
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Step 3 - Restore R0
//MOV R0, #0 = 0xE3A00000
shift_in[0] = 0xE3A00000; //Instruct 3
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 4
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 5
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//LDR R0, [R0] = 0xE5900000
shift_in[0] = 0xE5900000; //Instruct 6
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 7
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 8
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//R0 - put the value of R0 to the data bus
shift_in[0] = r0;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Write the value obtained from data bus to R0
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Step 4 - Set SYSTEM speed flag
//NOP
shift_in[0] = ARM7TDMI_NOP; //Instruct 9
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP + SYSTEM SPEED
shift_in[0] = ARM7TDMI_NOP; //Instruct 10
shift_in[1] = ARM7TDMI_SYSTEM_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
/*
* After move the new value to register PC, 10 instructions have been
* executed so far. To exit from DEBUG state and resume the normal
* operation of the program under debug, 10 instructions backwards.
*/
//B -10 = 0xEAFFFFF6
shift_in[0] = 0xEAFFFFF6; //Final branch
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
}else{ //Enter DEBUG from THUMB state
//Step 1 - Read R0 & Write the new value of PC to R0
pc &= 0xFFFFFFFE; //Align
status = arm7tdmi_core_rd_reg(ARM7TDMI_R0, &r0);
status = arm7tdmi_core_wri_reg(ARM7TDMI_R0, pc + 1);
//Step 2 - Switch from ARM state back to THUMB state first
//BX R0 = 0xE12FFF10
shift_in[0] = 0xE12FFF10;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//NOP
shift_in[0] = ARM7TDMI_NOP;
shift_in[1] = ARM7TDMI_DEBUG_SPEED;
arm7tdmi_acs_sc1(shift_in, shift_out);
//Step 3 - Sbbtract R0 by 1
//SUB R0, #1 = 0x38013801
shift_in[0] = 0x38013801;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -