From 63e1e6e42b3cc60be8f94662985d9ddeeb6b5ef9 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Fri, 13 Dec 2024 15:39:21 +0100 Subject: [PATCH] [nrf fromtree] boards: nordic: remove custom JLink reset scheme Secure domain firmware v9.0.0 and onward no longer supports the non-essential domain reset procedure which was used in the custom JLink reset scheme for nrf54h20dk/nrf54h20/cpuapp, nrf54h20dk/nrf54h20/cpurad, nrf9280pdk/nrf9280/cpuapp and nrf9280pdk/nrf9280/cpurad. All resets done through the ADAC interface now do a global reset instead, which as of now "kills" the JLink session. Remove the custom reset behavior as it will not work anymore moving forward. This means that "monitor reset" in GDB can no longer be used to debug the application from the start of execution. Using current tooling, it is possible to debug from the start of execution by first resetting the cores into a halted state, starting cores other than the one you are debugging and then attaching GDB. For example: > nrfutil device reset --reset-kind RESET_VIA_SECDOM > nrfutil device go --core Network > west attach Signed-off-by: Jonathan Nilsen (cherry picked from commit 18250bd3126b11ae61fc0c7df44e3455178a7d9e) --- .../support/nrf54h20_cpuapp.JLinkScript | 252 +----------------- .../support/nrf54h20_cpurad.JLinkScript | 252 +----------------- .../support/nrf9280_cpuapp.JLinkScript | 252 +----------------- .../support/nrf9280_cpurad.JLinkScript | 252 +----------------- 4 files changed, 8 insertions(+), 1000 deletions(-) diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript index 28010addbf1..b1b96857399 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript @@ -1,260 +1,12 @@ -// Constants specific to the application core __constant U32 _CPUCONF_ADDR = 0x52011000; -__constant U32 _PROCESSOR_ID = 2; -__constant U32 _DOMAIN_ID = 2; -__constant U32 _NUM_OTHER_PROCESSORS = 1; -const U32 _OTHER_PROCESSOR_IDS[1] = {3}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript index 5c2065307ff..e1861ae8c97 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript @@ -1,159 +1,6 @@ -// Constants specific to the radio core __constant U32 _CPUCONF_ADDR = 0x53011000; -__constant U32 _PROCESSOR_ID = 3; -__constant U32 _DOMAIN_ID = 3; -__constant U32 _NUM_OTHER_PROCESSORS = 1; -const U32 _OTHER_PROCESSOR_IDS[1] = {2}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - int ConfigTargetSettings(void) { JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); @@ -162,107 +9,12 @@ int ConfigTargetSettings(void) return 0; } -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript index 5791a7bed9b..b1b96857399 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript @@ -1,260 +1,12 @@ -// Constants specific to the application core __constant U32 _CPUCONF_ADDR = 0x52011000; -__constant U32 _PROCESSOR_ID = 2; -__constant U32 _DOMAIN_ID = 2; -__constant U32 _NUM_OTHER_PROCESSORS = 2; -const U32 _OTHER_PROCESSOR_IDS[2] = {4, 3}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; } diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript index 02b84dcc970..e1861ae8c97 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript @@ -1,159 +1,6 @@ -// Constants specific to the radio core __constant U32 _CPUCONF_ADDR = 0x53011000; -__constant U32 _PROCESSOR_ID = 3; -__constant U32 _DOMAIN_ID = 3; -__constant U32 _NUM_OTHER_PROCESSORS = 2; -const U32 _OTHER_PROCESSOR_IDS[2] = {4, 2}; - -// Debug Halting Control and Status Register -__constant U32 _DHCSR_ADDR = 0xE000EDF0; -__constant U32 _DHCSR_DBGKEY = (0xA05F << 16); -__constant U32 _DHCSR_C_DEBUGEN = (1 << 0); -__constant U32 _DHCSR_C_HALT = (1 << 1); - -// Debug Exception and Monitor Control Register -__constant U32 _DEMCR_ADDR = 0xE000EDFC; -__constant U32 _DEMCR_VC_CORERESET = (1 << 0); -__constant U32 _DEMCR_TRCENA = (1 << 24); - -// CPU wait enable register __constant U32 _CPUCONF_CPUWAIT_OFFSET = 0x50C; -// CTRL-AP -__constant U32 _CTRLAP_ID = 4; -__constant U32 _CTRLAP_READY_BANK = 0; -__constant U32 _CTRLAP_READY_OFFSET = 1; -__constant U32 _CTRLAP_READY = 0; -__constant U32 _CTRLAP_MAILBOX_BANK = 1; -__constant U32 _CTRLAP_MAILBOX_TXDATA_OFFSET = 0; -__constant U32 _CTRLAP_MAILBOX_TXSTATUS_OFFSET = 1; -__constant U32 _CTRLAP_MAILBOX_RXDATA_OFFSET = 2; -__constant U32 _CTRLAP_MAILBOX_RXSTATUS_OFFSET = 3; -__constant U32 _CTRLAP_MAILBOX_NO_DATA_PENDING = 0; -__constant U32 _CTRLAP_MAILBOX_DATA_PENDING = 1; -__constant int _CTRLAP_TIMEOUT_MS = 500; - -// ADAC transaction buffers -static U32 _adacTx[20]; -static U32 _adacRx[20]; - -// Failed to send to the CTRL-AP MAILBOX -__constant int _ERR_TX = -1; -// Failed to receive from the CTRL-AP MAILBOX -__constant int _ERR_RX = -2; -// ADAC command returned an error -__constant int _ERR_REPLY = -3; - -// Wait for an AP register read to return the expected value. -int _WaitForDataStatus(U32 regOffset, int expectedStatus) -{ - int status; - int ret; - int start; - int elapsed; - - status = 0; - start = JLINK_GetTime(); - elapsed = 0; - - do { - ret = JLINK_CORESIGHT_ReadDAP(regOffset, 1, &status); - elapsed = JLINK_GetTime() - start; - } while ((ret < 0 || status != expectedStatus) && (elapsed < _CTRLAP_TIMEOUT_MS)); - - if (ret < 0) { - return ret; - } - - return status; -} - -// Continuously read from the CTRL-AP MAILBOX until there is no more pending data. -void _DrainMailbox(void) -{ - int ret; - int status; - int data; - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - while (ret >= 0 && status == _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, 1, &status); - } -} - -// Perform an ADAC transaction by: -// * writing the given sequence of words to MAILBOX.TXDATATA, waiting for MAILBOX.TXSTATUS -// readiness before each write. -// * reading a sequence of words from MAILBOX.RXDATA, waiting for MAILBOX.RXSTATUS readiness before -// each read. -// -// The message to send is read from _adacTx and the reply is written to _adacRx. -// Optionally checks if a single data word is returned and returns an error if it is non-zero. -// -// Assumes that the correct AP and AP bank for CTRL-AP MAILBOX has been selected in the DP. -int _DoAdacTransaction(int checkReplyStatus) -{ - int numWords; - int ret; - int data; - int i; - - i = 0; - numWords = 2 + (_adacTx[1] >> 2); // Length based on the length field of the message - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_TXSTATUS_OFFSET, - _CTRLAP_MAILBOX_NO_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_NO_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP TX readiness - result: ", - ret); - return _ERR_TX; - } - - ret = JLINK_CORESIGHT_WriteDAP(_CTRLAP_MAILBOX_TXDATA_OFFSET, 1, _adacTx[i]); - if (ret < 0) { - JLINK_SYS_Report1("Failed to write CTRL-AP TX data - result: ", ret); - return _ERR_TX; - } - - i += 1; - } - - i = 0; - numWords = 2; // Minimum message length - - while (i < numWords) { - ret = _WaitForDataStatus(_CTRLAP_MAILBOX_RXSTATUS_OFFSET, - _CTRLAP_MAILBOX_DATA_PENDING); - if (ret != _CTRLAP_MAILBOX_DATA_PENDING) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - ret = JLINK_CORESIGHT_ReadDAP(_CTRLAP_MAILBOX_RXDATA_OFFSET, 1, &data); - if (ret < 0) { - JLINK_SYS_Report1("Failed to read CTRL-AP RX data - result: ", ret); - return _ERR_RX; - } - - if (i == 1) { - // Update total length based on the message length field - numWords = 2 + (data >> 2); - } - - _adacRx[i] = data; - i += 1; - } - - if (checkReplyStatus && _adacRx[1] == 4 && _adacRx[2] != 0) { - JLINK_SYS_Report1("ADAC command failed with status: ", _adacRx[2]); - return _ERR_REPLY; - } - - return 0; -} - int ConfigTargetSettings(void) { JLINK_ExecCommand("CORESIGHT_AddAP = Index=1 Type=AHB-AP"); @@ -162,107 +9,12 @@ int ConfigTargetSettings(void) return 0; } -int ResetTarget(void) +int SetupTarget(void) { - int err; - U32 adacMajorVersion; - U32 i; - - // Select CTRL-AP bank 0, used for the READY register - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_READY_BANK << 4)); - - // Wait for the READY register to indicate that the AP can be used. - err = _WaitForDataStatus(_CTRLAP_READY_OFFSET, _CTRLAP_READY); - if (err < 0) { - JLINK_SYS_Report1("Timed out waiting for CTRL-AP readiness - result: ", err); - return -1; - } - - // Select CTRL-AP bank 1, used for the MAILBOX registers for ADAC communication - JLINK_CORESIGHT_WriteDAP(JLINK_CORESIGHT_DP_REG_SELECT, 0, - (_CTRLAP_ID << 24) | (_CTRLAP_MAILBOX_BANK << 4)); - - // Extract any pre-existing data from the mailbox in case there was previously - // an aborted transaction. - _DrainMailbox(); - - // Read the ADAC version - _adacTx[0] = 0xA3000000; // Command VERSION - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // Type 0 (ADAC version) - err = _DoAdacTransaction(0); - if (err < 0) { - return -1; - } - - adacMajorVersion = (_adacRx[2] >> 24) & 0xff; - JLINK_SYS_Report1("ADAC major version: ", adacMajorVersion); - - if (adacMajorVersion >= 2) { - // There is a very small chance that this command fails if the domain reset itself - // at the exact same time the command was issued. Therefore we retry a few times. - i = 0; - while (i < 3) { - // Reset non-essential domains - _adacTx[0] = 0xA30A0000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000; // (reserved) - err = _DoAdacTransaction(1); - if (err >= 0) { - break; - } else if (err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - - // Start the core in halted mode - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_PROCESSOR_ID << 16); // Own processor, Flags HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - - // Start other cores normally (will fail silently if no firmware is present) - i = 0; - while (i < _NUM_OTHER_PROCESSORS) { - _adacTx[0] = 0xA3090000; // Command START - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x00000000 | - (_OTHER_PROCESSOR_IDS[i] << 16); // Other processor, No flags - err = _DoAdacTransaction(0); - if (err < 0 && err != _ERR_REPLY) { - return -1; - } - - i = i + 1; - } - } else { - // Reset single domain via legacy implementation - _adacTx[0] = 0xA3030000; // Command RESET - _adacTx[1] = 0x00000004; // Data length 4 bytes - _adacTx[2] = 0x01000000 | (_DOMAIN_ID << 16); // Own domain, Mode HALT - err = _DoAdacTransaction(1); - if (err < 0) { - return -1; - } - } - - // Halt the CPU - JLINK_MEM_WriteU32(_DHCSR_ADDR, (_DHCSR_DBGKEY | _DHCSR_C_HALT | _DHCSR_C_DEBUGEN)); - - // Set vector catch on reset (to halt the CPU immediately after reset) - JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); + JLINK_TARGET_Halt(); // Disable CPU wait JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); - // Clear vector catch stuff - JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); - return 0; }