/********************************************************************* * SEGGER Microcontroller GmbH * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1995 - 2018 SEGGER Microcontroller GmbH * * * * www.segger.com Support: support@segger.com * * * ********************************************************************** ---------------------------------------------------------------------- Purpose : J-Link script file for BeagleBoard which has a TI OMAP3530 (Cortex-A8 core) on it. By default, only the TI ICEPick is in the JTAG chain which means that we have to add the Cortex-A8 by configuring the ICEPick. Moreover, the OMAP3530 also requires to set the DEBGEN signal in order to allow debugging. ---------------------------END-OF-HEADER------------------------------ */ /********************************************************************* * * _StoreSelDP */ void _StoreSelDP(void) { JTAG_StoreIR(0xA); // DPACC command JTAG_StoreClocks(1); } /********************************************************************* * * _StoreSelAP */ void _StoreSelAP(void) { JTAG_StoreIR(0xB); // APACC command JTAG_StoreClocks(1); } /********************************************************************* * * _StoreTriggerReadAPDPReg * * Function description * Triggers a read of an AP or DP register. Depends on the previous command (DPACC / APACC) */ int _StoreTriggerReadAPDPReg(unsigned int RegIndex) { U32 v; int BitPos; // // Write 35 bits (32 bits data, 2 bits addr, 1 bit RnW) // v = 1; // 1 indicates read access v |= (RegIndex << 1); JLINK_JTAG_StartDR(); BitPos = JLINK_JTAG_WriteDRCont(v, 3); v = 0; JLINK_JTAG_WriteDREnd(v, 32); JTAG_StoreClocks(8); return BitPos; } /********************************************************************* * * _StoreWriteAPDPReg * * Function description * Writes an AP or DP register. Depends on the previous command (DPACC / APACC) */ int _StoreWriteAPDPReg(unsigned int RegIndex, U32 Data) { U32 v; int BitPos; // // Write 35 bits (32 bits data, 2 bits addr, 1 bit RnW) // v = 0; // 0 indicates write access v |= (RegIndex << 1); JLINK_JTAG_StartDR(); BitPos = JLINK_JTAG_WriteDRCont(v, 3); v = Data; JLINK_JTAG_WriteDREnd(v, 32); JTAG_StoreClocks(8); return BitPos; } /********************************************************************* * * _InitIcePick * * Function description * Configures the ICEPick so that the CPU core also becomes * visible in the JTAG chain. */ int _InitIcePick(void) { int BitPos; int v; int DPIdCode; int ICEPickIdCode; int i; int Speed; Report("J-Link script: Init ICEPick"); JTAG_Reset(); // Perform TAP reset and J-Link JTAG auto-detection if (JTAG_TotalIRLen != 6) { MessageBox("Can not find Beagle eval board (IRLen mismatch)"); } JTAG_DRPre = 0; JTAG_DRPost = 0; JTAG_IRPre = 0; JTAG_IRPost = 0; JTAG_IRLen = 6; Speed = JTAG_Speed; JTAG_Speed = 50; // // Check IDCODE of ICEPick (do not confuse with ICEPICKCODE or IDCODE of JTAG-DP) // JTAG_WriteIR(4); // IDCODE instruction for ICEPick device BitPos = JTAG_WriteDR(0x00000000, 32); v = JTAG_GetU32(BitPos); // // Seems the part number of the ICEPick has been changed // between BeagleBoard and BeagleBoard-xM, so we have // to check both part numbers. // if (((v & 0x0FFFFFFF) != 0x0B7AE02F) && // ICEPICK-IDCODE of ICEPICK on BeagleBoard ((v & 0x0FFFFFFF) != 0x0B89102F) // ICEPICK-IDCODE of ICEPICK on BeagleBoard XM ) { MessageBox1("Can not find ICE-Pick (IDCODE mismatch). Expected 0x0B7AE02F / 0x0B89102F, found: ", v); return 1; } ICEPickIdCode = v; // // Read ICEPICKCODE // JTAG_WriteIR(5); BitPos = JTAG_WriteDR(0x00000000, 32); v = JTAG_GetU32(BitPos); if ((v & 0x0000FFF0) != 0x00001CC0) { MessageBox("Connected module is not an ICEPick Module (ICEPICKCODE mismatch)"); return 1; } // // Put ARM core in JTAG chain // JTAG_WriteIR(7); // CONNECT JTAG_WriteDR(0x89, 8); // The ICEPick documentation (SPRUE64, 2.6 CONNECT instruction: Accessing the debug connect register). Bit 7 set means: Write debug connect register. We write 0x9 to the debug connect register which is the debug connect key. JTAG_WriteIR(2); // ROUTER (Accessing the mapped registers) v = 0 | (1 << 31) // Write mapped register | (0x23 << 24) // SDTAP3 register | (1 << 13) // Debug connect | (1 << 8) // TAP select | (1 << 3) // Force active ; JTAG_WriteDR(v, 32); JTAG_WriteIR(0x3F); // Bypass JTAG_WriteClocks(10); // // Configure JTAG chain, so J-Link knows to which devices it has to "talk" to. // CPU core is in scan chain now, so we have to re-configure the JTAG chain settings // JTAG_DRPre = 0; JTAG_DRPost = 1; JTAG_IRPre = 0; JTAG_IRPost = 6; JTAG_IRLen = 4; CPU=CORTEX_A8; JTAG_AllowTAPReset=0; // // Check JTAG-DP ID // On the Cortex-A OMAP devices it seems that the manufacturer field of the JTAG-DP ID // is not set to ARM JEDEC ID but to TI JEDEC ID which is not really CoreSight compliant. // So we check if one of these manufacturer codes match. // JTAG_StoreIR(0xE); // Read JTAG-DP IDCODE register v = 0; BitPos = JTAG_StoreDR(v, 32); // Get ID v = JTAG_GetU32(BitPos); if (((v & 0x00000FFF) != 0x0000002F) && // TI JEDEC ID ((v & 0x00000FFF) != 0x00000477) // ARM JEDEC ID ) { MessageBox("Can not find JTAG-DP (IDCODE mismatch)"); } // // Set JTAG Ids for all devices in the JTAG chain // JTAG_SetDeviceId(0, v); // JTAG-DP JTAG_SetDeviceId(1, ICEPickIdCode); // ICEPick // // Set DBGEN signal in order to enable invasive debugging // _StoreSelDP(); _StoreWriteAPDPReg(1, 0xF0000000); // Write JTAG-DP CTRL/STAT in order to power-up debug port v = 0 | (1 << 24) // Select AP 1 which is the APB-AP | (0 << 4) // Select Bank 0 ; _StoreWriteAPDPReg(2, v); // Write JTAG-DP SELECT register, in order to select the APB-AP. On the OMAP3550 AP[1] is the APB-AP _StoreSelAP(); _StoreWriteAPDPReg(0, 0x80000012); // Write APB-AP CSW _StoreWriteAPDPReg(1, 0xD401D030); // Write APB-AP TAR v = (1 << 13); // Set DBGEN signal _StoreWriteAPDPReg(3, v); // Write APB-AP DRW _StoreSelDP(); JTAG_WriteClocks(1); // Make sure all JTAG buffers are cleared JTAG_Speed = Speed; } /********************************************************************* * * _SetBP */ void _SetBP(int DbgRegBaseAddr) { __int64 Ctrl; // // Select & setup APB-AP // _StoreSelDP(); _StoreWriteAPDPReg(2, (1 << 24) | (0 << 4)); // Select AP[1], bank 0 _StoreSelAP(); Ctrl = 0 | (2 << 0) // AP-access size. Fixed to 2: 32-bit | (1 << 4) // Auto increment TAR after read/write access. Increment is NOT performed on access to banked data registers 0-3. | (1 << 31) // Enable software access to the Debug APB bus. ; _StoreWriteAPDPReg(0, Ctrl); // // Step 1. Disable the breakpoint being set. // _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x50 << 2)); _StoreWriteAPDPReg(3, 0x00000000); // // Step 2. Write address to the BVR, leaving the bottom 2 bits zero. // _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x40 << 2)); _StoreWriteAPDPReg(3, 0x00014000); // // Step 3. Write the mask and control register to enable the breakpoint. // _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x50 << 2)); _StoreWriteAPDPReg(3, 7 | (0xF << 5) | (0 << 20)); JTAG_WriteClocks(1); // Make sure that JTAG buffers are empty and breakpoint is set } /********************************************************************* * * ResetTarget */ void ResetTarget(void) { int DbgRegBaseAddr; int Speed; int BitPos; int Ctrl; __int64 v; Report("J-Link script: Reset"); Speed = JTAG_Speed; JTAG_Speed = 100; DbgRegBaseAddr = 0x54011000; // // Set breakpoint to halt target as fast as possible after reset // _SetBP(DbgRegBaseAddr); // // Setup JTAG config to "talk" to the ICEPick, so we can use the JTAG API functions // JTAG_DRPre = 1; JTAG_DRPost = 0; JTAG_IRPre = 4; JTAG_IRPost = 0; JTAG_IRLen = 6; // // Perform reset via ICEPick system control register, by setting the SysReset bit // JTAG_StoreIR(2); // Cmd: ROUTER v = 0x01000000; // Read SYS_CNTL JTAG_StoreDR(v, 32); // Send read register command BitPos = JTAG_StoreDR(v, 32); // Shift out register content v = JTAG_GetU32(BitPos); v &= 0x00FFFFFF; v |= 0x81000001; // Write SYS_CNTL and set SysReset bit JTAG_StoreDR(v, 32); JTAG_WriteClocks(10); // The reset needs some time to get active // // Setup JTAG config to "talk" to the CPU core again // JTAG_DRPre = 0; JTAG_DRPost = 1; JTAG_IRPre = 0; JTAG_IRPost = 6; JTAG_IRLen = 4; // // Check if CPU is halted. If not, halt it. // Select & setup APB-AP // _StoreSelDP(); _StoreWriteAPDPReg(2, (1 << 24) | (0 << 4)); // Select AP[1], bank 0 _StoreSelAP(); Ctrl = 0 | (2 << 0) // AP-access size. Fixed to 2: 32-bit | (1 << 4) // Auto increment TAR after read/write access. Increment is NOT performed on access to banked data registers 0-3. | (1 << 31) // Enable software access to the Debug APB bus. ; _StoreWriteAPDPReg(0, Ctrl); // // Read DSCR to check if CPU is halted // _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x22 << 2)); _StoreTriggerReadAPDPReg(3); _StoreSelDP(); BitPos = _StoreTriggerReadAPDPReg(3); v = JTAG_GetU32(BitPos + 3); _StoreSelAP(); if ((v & 1) == 0) { // // If CPU did not halt after reset, halt it // Report("J-Link script: Core did not halt after reset. Halting core..."); v |= (1 << 14); _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x22 << 2)); // Enable debug halt mode by writing the DSCR _StoreWriteAPDPReg(3, v); _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x24 << 2)); // Write DRCR to halt CPU _StoreWriteAPDPReg(3, 1); JTAG_WriteClocks(1); } // // Remove breakpoint // _StoreWriteAPDPReg(1, DbgRegBaseAddr + (0x50 << 2)); _StoreWriteAPDPReg(3, 0); _StoreSelDP(); JTAG_WriteClocks(1); JTAG_Speed = Speed; } /********************************************************************* * * InitEMU */ void InitEMU(void) { EMU_ETB_IsPresent = 0; } /********************************************************************* * * InitTarget */ void InitTarget(void) { int v; Report("Beagle Board OMAP3530 (Cortex-A8 core) J-Link script"); JTAG_TRSTPin = 0; SYS_Sleep(50); JTAG_TRSTPin = 1; SYS_Sleep(50); JTAG_Write(0x1F, 0, 6); _InitIcePick(); }