diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index bf96741de22..2b2473f92b5 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -11,9 +11,7 @@ compatible = "nordic,owned-memory"; reg = <0x2f010000 DT_SIZE_K(260)>; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f010000 0x41000>; @@ -35,9 +33,7 @@ compatible = "nordic,owned-memory"; reg = <0x2f051000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f051000 0x1000>; @@ -55,9 +51,7 @@ compatible = "nordic,owned-memory"; reg = <0x2f0be000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f0be000 0x1000>; @@ -72,8 +66,8 @@ compatible = "nordic,owned-memory"; reg = <0x2f0bf000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; + nordic,access = , + ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f0bf000 0x1000>; @@ -87,40 +81,32 @@ }; }; - shared_ram20_region: memory@2f88f000 { - reg = <0x2f88f000 DT_SIZE_K(4)>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f88f000 0x1000>; - - cpuapp_cpusys_ipc_shm: memory@ce0 { - reg = <0xce0 0x80>; - }; + cpuapp_cpusys_ipc_shm: memory@2f88fce0 { + reg = <0x2f88fce0 0x80>; + }; - cpusys_cpuapp_ipc_shm: memory@d60 { - reg = <0xd60 0x80>; - }; + cpusys_cpuapp_ipc_shm: memory@2f88fd60 { + reg = <0x2f88fd60 0x80>; + }; - cpurad_cpusys_ipc_shm: memory@e00 { - reg = <0xe00 0x80>; - }; + cpurad_cpusys_ipc_shm: memory@2f88fe00 { + reg = <0x2f88fe00 0x80>; + }; - cpusys_cpurad_ipc_shm: memory@e80 { - reg = <0xe80 0x80>; - }; + cpusys_cpurad_ipc_shm: memory@2f88fe80 { + reg = <0x2f88fe80 0x80>; }; /* - * NOTE: perm-execute is not required as FLPR has a direct - * bridge with RAM21, bypassing MPC. + * NOTE: FLPR has a direct bridge with RAM21 that bypasses MPC. + * This means that when this region is marked as non-executable, + * only FLPR can execute code from it. */ ram21_region: memory@2f890000 { compatible = "nordic,owned-memory"; status = "disabled"; reg = <0x2f890000 DT_SIZE_K(64)>; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f890000 0x10000>; @@ -151,9 +137,7 @@ compatible = "nordic,owned-memory"; reg = <0x2fc00000 DT_SIZE_K(64)>; status = "disabled"; - perm-read; - perm-write; - perm-execute; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2fc00000 0x10000>; @@ -171,33 +155,24 @@ }; }; - shared_ram3x_region: memory@2fc12000 { - compatible = "nordic,owned-memory"; - reg = <0x2fc12000 DT_SIZE_K(8)>; + cpuapp_dma_region: memory@2fc12000 { + compatible = "nordic,owned-memory", "zephyr,memory-region"; + reg = <0x2fc12000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2fc12000 0x2000>; - - cpuapp_dma_region: memory@e80 { - compatible = "zephyr,memory-region"; - reg = <0xe80 DT_SIZE_K(4)>; - status = "disabled"; - #memory-region-cells = <0>; - zephyr,memory-region = "DMA_RAM3x_APP"; - zephyr,memory-attr = <( DT_MEM_DMA )>; - }; + #memory-region-cells = <0>; + nordic,access = ; + zephyr,memory-region = "DMA_RAM3x_APP"; + zephyr,memory-attr = <( DT_MEM_DMA )>; + }; - cpurad_dma_region: memory@1e80 { - compatible = "zephyr,memory-region"; - reg = <0x1e80 0x80>; - status = "disabled"; - #memory-region-cells = <0>; - zephyr,memory-region = "DMA_RAM3x_RAD"; - zephyr,memory-attr = <( DT_MEM_DMA )>; - }; + cpurad_dma_region: memory@2fc13000 { + compatible = "nordic,owned-memory", "zephyr,memory-region"; + reg = <0x2fc13000 DT_SIZE_K(1)>; + status = "disabled"; + #memory-region-cells = <0>; + nordic,access = ; + zephyr,memory-region = "DMA_RAM3x_RAD"; + zephyr,memory-attr = <( DT_MEM_DMA )>; }; }; }; @@ -206,9 +181,7 @@ cpurad_rx_partitions: cpurad-rx-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-execute; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; @@ -220,9 +193,7 @@ cpuapp_rx_partitions: cpuapp-rx-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-execute; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; @@ -242,9 +213,7 @@ cpuapp_rw_partitions: cpuapp-rw-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 3c7a5436a08..f9dcb59aba8 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -123,14 +123,6 @@ status = "okay"; }; -&cpuapp_cpurad_ram0x_region { - status = "okay"; -}; - -&shared_ram3x_region { - status = "okay"; -}; - &ram21_region { status = "okay"; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index b100dbb8676..69c25117807 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -39,10 +39,6 @@ }; }; -&shared_ram3x_region { - status = "okay"; -}; - &cpuapp_cpurad_ram0x_region { status = "okay"; }; diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript index ffa1beed1ed..28010addbf1 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpuapp.JLinkScript @@ -1,29 +1,248 @@ +// 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); +__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); +__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_ADDR = 0x5201150C; +__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 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; + } -int ResetTarget(void) { - // ADAC reset - JLINK_CORESIGHT_WriteDP(2, 0x04000010); - JLINK_CORESIGHT_WriteAP(0, 0xA3030000); - JLINK_CORESIGHT_WriteAP(0, 0x00000004); - JLINK_CORESIGHT_WriteAP(0, 0x01020000); + // 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; + } - JLINK_SYS_Sleep(100); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); + 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)); @@ -32,7 +251,7 @@ int ResetTarget(void) { JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); // Disable CPU wait - JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); // Clear vector catch stuff JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); diff --git a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript index 2f1802801c1..5c2065307ff 100644 --- a/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript +++ b/boards/nordic/nrf54h20dk/support/nrf54h20_cpurad.JLinkScript @@ -1,36 +1,256 @@ +// 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); +__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); +__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_ADDR = 0x5301150C; +__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 -int ConfigTargetSettings(void) { + 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"); CORESIGHT_IndexAHBAPToUse = 1; return 0; } -int ResetTarget(void) { - // ADAC reset - JLINK_CORESIGHT_WriteDP(2, 0x04000010); - JLINK_CORESIGHT_WriteAP(0, 0xA3030000); - JLINK_CORESIGHT_WriteAP(0, 0x00000004); - JLINK_CORESIGHT_WriteAP(0, 0x01030000); +int ResetTarget(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; + } - JLINK_SYS_Sleep(100); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); + 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)); @@ -39,7 +259,7 @@ int ResetTarget(void) { JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); // Disable CPU wait - JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); // Clear vector catch stuff JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-memory_map.dtsi b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-memory_map.dtsi index 78e3be8825f..0127998509e 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-memory_map.dtsi +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-memory_map.dtsi @@ -15,9 +15,7 @@ compatible = "nordic,owned-memory"; reg = <0x2f011000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f011000 0x1000>; @@ -35,9 +33,7 @@ compatible = "nordic,owned-memory"; reg = <0x2f012000 DT_SIZE_K(516)>; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f012000 0x81000>; @@ -59,8 +55,8 @@ compatible = "nordic,owned-memory"; reg = <0x2f0cf000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; + nordic,access = , + ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f0cf000 0x1000>; @@ -75,8 +71,11 @@ }; cpuapp_cpucell_ram0x_region: memory@2f0d0000 { + compatible = "nordic,owned-memory"; reg = <0x2f0d0000 DT_SIZE_K(36)>; status = "disabled"; + nordic,access = , + ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f0d0000 0x9000>; @@ -99,61 +98,27 @@ }; }; - /* Shared memory ownership. - * TODO: - * remove these two after https://github.com/zephyrproject-rtos/zephyr/pull/72273 - * and let cpuapp_cpucell_ram0x_region use the `access` binding to describe - * the shared memory ownership. - */ - - cpuapp_cpucell_ipc_shm: memory@2 { - compatible = "nordic,owned-memory"; - reg = <0x2f0d0000 DT_SIZE_K(36)>; - owner-id = <2>; - perm-read; - perm-write; - status = "disabled"; + cpuapp_cpusys_ipc_shm: memory@2f88fce0 { + reg = <0x2f88fce0 0x80>; }; - cpucell_cpuapp_ipc_shm: memory@4 { - compatible = "nordic,owned-memory"; - reg = <0x2f0d0000 DT_SIZE_K(36)>; - owner-id = <4>; - perm-read; - perm-write; - status = "disabled"; + cpusys_cpuapp_ipc_shm: memory@2f88fd60 { + reg = <0x2f88fd60 0x80>; }; - shared_ram20_region: memory@2f88f000 { - reg = <0x2f88f000 DT_SIZE_K(4)>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f88f000 0x1000>; - - cpuapp_cpusys_ipc_shm: memory@ce0 { - reg = <0xce0 0x80>; - }; - - cpusys_cpuapp_ipc_shm: memory@d60 { - reg = <0xd60 0x80>; - }; - - cpurad_cpusys_ipc_shm: memory@e00 { - reg = <0xe00 0x80>; - }; + cpurad_cpusys_ipc_shm: memory@2f88fe00 { + reg = <0x2f88fe00 0x80>; + }; - cpusys_cpurad_ipc_shm: memory@e80 { - reg = <0xe80 0x80>; - }; + cpusys_cpurad_ipc_shm: memory@2f88fe80 { + reg = <0x2f88fe80 0x80>; }; ram21_region: memory@2f890000 { compatible = "nordic,owned-memory"; status = "disabled"; reg = <0x2f890000 DT_SIZE_K(32)>; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f890000 0x8000>; @@ -172,9 +137,7 @@ compatible = "nordic,owned-memory"; reg = <0x2fc00000 DT_SIZE_K(24)>; status = "disabled"; - perm-read; - perm-write; - perm-execute; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2fc00000 0x6000>; @@ -192,33 +155,24 @@ }; }; - shared_ram3x_region: memory@2fc06000 { - compatible = "nordic,owned-memory"; - reg = <0x2fc06000 DT_SIZE_K(8)>; + cpuapp_dma_region: memory@2fc06000 { + compatible = "nordic,owned-memory", "zephyr,memory-region"; + reg = <0x2fc06000 DT_SIZE_K(4)>; status = "disabled"; - perm-read; - perm-write; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2fc06000 0x4000>; - - cpuapp_dma_region: memory@0 { - compatible = "zephyr,memory-region"; - reg = <0x0 DT_SIZE_K(4)>; - status = "disabled"; - #memory-region-cells = <0>; - zephyr,memory-region = "DMA_RAM3x_APP"; - zephyr,memory-attr = <( DT_MEM_DMA )>; - }; + #memory-region-cells = <0>; + nordic,access = ; + zephyr,memory-region = "DMA_RAM3x_APP"; + zephyr,memory-attr = <( DT_MEM_DMA )>; + }; - cpurad_dma_region: memory@1000 { - compatible = "zephyr,memory-region"; - reg = <0x1000 0x80>; - status = "disabled"; - #memory-region-cells = <0>; - zephyr,memory-region = "DMA_RAM3x_RAD"; - zephyr,memory-attr = <( DT_MEM_DMA )>; - }; + cpurad_dma_region: memory@2fc07000 { + compatible = "nordic,owned-memory", "zephyr,memory-region"; + reg = <0x2fc07000 DT_SIZE_K(1)>; + status = "disabled"; + #memory-region-cells = <0>; + nordic,access = ; + zephyr,memory-region = "DMA_RAM3x_RAD"; + zephyr,memory-attr = <( DT_MEM_DMA )>; }; }; }; @@ -227,9 +181,7 @@ cpurad_rx_partitions: cpurad-rx-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-execute; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; @@ -241,9 +193,7 @@ cpuapp_rx_partitions: cpuapp-rx-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-execute; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; @@ -259,9 +209,7 @@ cpuapp_rw_partitions: cpuapp-rw-partitions { compatible = "nordic,owned-partitions", "fixed-partitions"; status = "disabled"; - perm-read; - perm-write; - perm-secure; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts index c01824a2297..d9611599386 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpuapp.dts @@ -120,19 +120,7 @@ status = "okay"; }; -&cpuapp_cpurad_ram0x_region { - status = "okay"; -}; - -&cpuapp_cpucell_ipc_shm { - status = "okay"; -}; - -&cpucell_cpuapp_ipc_shm { - status = "okay"; -}; - -&shared_ram3x_region { +&cpuapp_cpucell_ram0x_region { status = "okay"; }; diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.dts b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.dts index a45a00e5905..c309e346d57 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.dts +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280_cpurad.dts @@ -40,10 +40,6 @@ }; }; -&shared_ram3x_region { - status = "okay"; -}; - &cpuapp_cpurad_ram0x_region { status = "okay"; }; diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript index ffa1beed1ed..5791a7bed9b 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpuapp.JLinkScript @@ -1,29 +1,248 @@ +// 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); +__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); +__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_ADDR = 0x5201150C; +__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 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; + } -int ResetTarget(void) { - // ADAC reset - JLINK_CORESIGHT_WriteDP(2, 0x04000010); - JLINK_CORESIGHT_WriteAP(0, 0xA3030000); - JLINK_CORESIGHT_WriteAP(0, 0x00000004); - JLINK_CORESIGHT_WriteAP(0, 0x01020000); + // 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; + } - JLINK_SYS_Sleep(100); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); + 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)); @@ -32,7 +251,7 @@ int ResetTarget(void) { JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); // Disable CPU wait - JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); // Clear vector catch stuff JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); diff --git a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript index 2f1802801c1..02b84dcc970 100644 --- a/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript +++ b/boards/nordic/nrf9280pdk/support/nrf9280_cpurad.JLinkScript @@ -1,36 +1,256 @@ +// 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); +__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); +__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_ADDR = 0x5301150C; +__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 -int ConfigTargetSettings(void) { + 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"); CORESIGHT_IndexAHBAPToUse = 1; return 0; } -int ResetTarget(void) { - // ADAC reset - JLINK_CORESIGHT_WriteDP(2, 0x04000010); - JLINK_CORESIGHT_WriteAP(0, 0xA3030000); - JLINK_CORESIGHT_WriteAP(0, 0x00000004); - JLINK_CORESIGHT_WriteAP(0, 0x01030000); +int ResetTarget(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; + } - JLINK_SYS_Sleep(100); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); - JLINK_CORESIGHT_ReadAP(2); + 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)); @@ -39,7 +259,7 @@ int ResetTarget(void) { JLINK_MEM_WriteU32(_DEMCR_ADDR, (_DEMCR_VC_CORERESET | _DEMCR_TRCENA)); // Disable CPU wait - JLINK_MEM_WriteU32(_CPUCONF_CPUWAIT_ADDR, 0); + JLINK_MEM_WriteU32(_CPUCONF_ADDR + _CPUCONF_CPUWAIT_OFFSET, 0); // Clear vector catch stuff JLINK_MEM_WriteU32(_DEMCR_ADDR, _DEMCR_TRCENA); diff --git a/dts/bindings/mtd/nordic,owned-partitions.yaml b/dts/bindings/mtd/nordic,owned-partitions.yaml index bf42c13346a..6dd300ecb98 100644 --- a/dts/bindings/mtd/nordic,owned-partitions.yaml +++ b/dts/bindings/mtd/nordic,owned-partitions.yaml @@ -24,8 +24,7 @@ description: | rx-partitions { compatible = "nordic,owned-partitions"; - perm-read; - perm-execute; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; @@ -37,8 +36,7 @@ description: | rw-partitions { compatible = "nordic,owned-partitions"; - perm-read; - perm-write; + nordic,access = ; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/bindings/reserved-memory/nordic,owned-memory.yaml b/dts/bindings/reserved-memory/nordic,owned-memory.yaml index 9b13c965ac8..69f3e4f9f7b 100644 --- a/dts/bindings/reserved-memory/nordic,owned-memory.yaml +++ b/dts/bindings/reserved-memory/nordic,owned-memory.yaml @@ -8,17 +8,64 @@ description: | will be recorded in the UICR of the compiled domain. Memory ownership and access is then configured for the domain at boot time, based on the UICR. + Example: + + reserved-memory { + memory@2fc00000 { + compatible = "nordic,owned-memory"; + reg = <0x2fc00000 0x1000>; + status = "okay"; + nordic,access = , + ; + }; + }; + + A single local domain can request a memory region to be reserved on behalf of + multiple access owners. A single memory region shall be reserved by at most + one domain, by setting status "okay" on the associated node. For example, if + the region defined above is enabled by Application on behalf of Radiocore, + then the Radiocore's devicetree must set status "disabled" on that node. + + Each of the different owners may have a different set of permissions granted, + as also shown above. + + Note: one domain can also reserve memory for another domain and not itself. + Whichever domain has status "okay" set on the node does not need to be listed + as one of the access owners. + compatible: "nordic,owned-memory" -include: base.yaml +include: [base.yaml, "zephyr,memory-common.yaml"] properties: reg: required: true + nordic,access: + type: array + description: | + Array of (owner-id, permission-flags) pairs, where: + + - Owner ID represents the domain that will have access to this memory. + Valid values can be found in dts/common/nordic/.dtsi, + where they are defined as NRF_OWNER_ID_* + + - Permissions are encoded as a 32-bit bitfield, using the flags found in + include/zephyr/dt-bindings/reserved-memory/nordic-owned-memory.h, + where they are defined as NRF_PERM_* + + The same file defines all possible permission flag combinations. + For example, one can use: + + + as a shorthand for: + + owner-id: type: int + deprecated: true description: | + Deprecated, applies only if 'nordic,access' is not defined. Owner ID of the domain that will own this memory region. If not defined, the ownership will default to the domain being compiled. @@ -27,20 +74,35 @@ properties: perm-read: type: boolean - description: Owner has read access to the region. + deprecated: true + description: | + Deprecated, applies only if 'nordic,access' is not defined. + Owner has read access to the region. perm-write: type: boolean - description: Owner has write access to the region. + deprecated: true + description: | + Deprecated, applies only if 'nordic,access' is not defined. + Owner has write access to the region. perm-execute: type: boolean - description: Owner can execute code from the region. + deprecated: true + description: | + Deprecated, applies only if 'nordic,access' is not defined. + Owner can execute code from the region. perm-secure: type: boolean - description: Owner has secure-only access to the region. + deprecated: true + description: | + Deprecated, applies only if 'nordic,access' is not defined. + Owner has secure-only access to the region. non-secure-callable: type: boolean - description: Memory region is used for non-secure-callable code. + deprecated: true + description: | + Deprecated, applies only if 'nordic,access' is not defined. + Memory region is used for non-secure-callable code. diff --git a/dts/common/nordic/nrf54h20.dtsi b/dts/common/nordic/nrf54h20.dtsi index e73cf7a189e..4374246073b 100644 --- a/dts/common/nordic/nrf54h20.dtsi +++ b/dts/common/nordic/nrf54h20.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include /delete-node/ &sw_pwm; diff --git a/dts/common/nordic/nrf9280.dtsi b/dts/common/nordic/nrf9280.dtsi index 59f450aba1d..08223449076 100644 --- a/dts/common/nordic/nrf9280.dtsi +++ b/dts/common/nordic/nrf9280.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include /delete-node/ &sw_pwm; diff --git a/include/zephyr/dt-bindings/reserved-memory/nordic-owned-memory.h b/include/zephyr/dt-bindings/reserved-memory/nordic-owned-memory.h new file mode 100644 index 00000000000..90f43379372 --- /dev/null +++ b/include/zephyr/dt-bindings/reserved-memory/nordic-owned-memory.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESERVED_MEMORY_NORDIC_OWNED_MEMORY_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESERVED_MEMORY_NORDIC_OWNED_MEMORY_H_ + +#include + +/** + * @name Basic memory permission flags. + * @{ + */ + +/** Readable. */ +#define NRF_PERM_R BIT(0) +/** Writable. */ +#define NRF_PERM_W BIT(1) +/** Executable. */ +#define NRF_PERM_X BIT(2) +/** Secure-only. */ +#define NRF_PERM_S BIT(3) +/** Non-secure-callable. */ +#define NRF_PERM_NSC BIT(4) + +/** + * @} + */ + +/** + * @name Memory permission flag combinations. + * @note NRF_PERM_NSC overrides all other flags, so it is not included here. + * @{ + */ + +#define NRF_PERM_RW (NRF_PERM_R | NRF_PERM_W) +#define NRF_PERM_RX (NRF_PERM_R | NRF_PERM_X) +#define NRF_PERM_RS (NRF_PERM_R | NRF_PERM_S) +#define NRF_PERM_WX (NRF_PERM_W | NRF_PERM_X) +#define NRF_PERM_WS (NRF_PERM_W | NRF_PERM_S) +#define NRF_PERM_XS (NRF_PERM_X | NRF_PERM_S) +#define NRF_PERM_RWX (NRF_PERM_R | NRF_PERM_W | NRF_PERM_X) +#define NRF_PERM_RWS (NRF_PERM_R | NRF_PERM_W | NRF_PERM_S) +#define NRF_PERM_RXS (NRF_PERM_R | NRF_PERM_X | NRF_PERM_S) +#define NRF_PERM_WXS (NRF_PERM_W | NRF_PERM_X | NRF_PERM_S) +#define NRF_PERM_RWXS (NRF_PERM_R | NRF_PERM_W | NRF_PERM_X | NRF_PERM_S) + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESERVED_MEMORY_NORDIC_OWNED_MEMORY_H_ */ diff --git a/modules/hal_nordic/Kconfig.nrf_regtool b/modules/hal_nordic/Kconfig.nrf_regtool index 77944c5bb05..b057133aaf5 100644 --- a/modules/hal_nordic/Kconfig.nrf_regtool +++ b/modules/hal_nordic/Kconfig.nrf_regtool @@ -33,11 +33,4 @@ config NRF_REGTOOL_VERBOSITY 3. Print even more details, which are typically only useful for nrf-regtool developers. -config NRF_REGTOOL_EXTRA_GENERATE_ARGS - string "Extra arguments to 'nrf-regtool generate'" - help - List of additional arguments to every nrf-regtool invocation used for - generating hex files. Example value: "--fill all --fill-byte 0xff". - Run "nrf-regtool generate -h" to see all of the available options. - endmenu diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake index 099f44673f5..8e93a35adc8 100644 --- a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake @@ -1,16 +1,26 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -function(nrf_regtool_generate_hex_from_dts peripheral) - string(TOLOWER "${peripheral}.hex" generated_hex_name) - string(TOLOWER "${peripheral}_merged.hex" merged_hex_name) +function(nrf_regtool_generate_uicr generated_hex_file) + string(REPEAT "-v;" ${CONFIG_NRF_REGTOOL_VERBOSITY} verbosity) + execute_process( + COMMAND + ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src + ${NRF_REGTOOL} ${verbosity} uicr-compile + --edt-pickle-file ${EDT_PICKLE} + --product-name ${CONFIG_SOC} + --output-file ${generated_hex_file} + WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} + COMMAND_ERROR_IS_FATAL ANY + ) + message(STATUS "Generated UICR hex file: ${generated_hex_file}") +endfunction() +function(nrf_regtool_generate_peripheral peripheral generated_hex_file) # Prepare common argument sub-lists. string(REPEAT "-v;" ${CONFIG_NRF_REGTOOL_VERBOSITY} verbosity) list(TRANSFORM CACHED_DTS_ROOT_BINDINGS PREPEND "--bindings-dir;" OUTPUT_VARIABLE bindings_dirs) - separate_arguments(extra_args UNIX_COMMAND "${CONFIG_NRF_REGTOOL_EXTRA_GENERATE_ARGS}") - set(generated_hex_file ${PROJECT_BINARY_DIR}/${generated_hex_name}) execute_process( COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src @@ -25,29 +35,31 @@ function(nrf_regtool_generate_hex_from_dts peripheral) COMMAND_ERROR_IS_FATAL ANY ) message(STATUS "Generated ${peripheral} hex file: ${generated_hex_file}") - - if(NOT peripheral STREQUAL "UICR") - return() - endif() - - set(merged_hex_file ${PROJECT_BINARY_DIR}/${merged_hex_name}) - set_property(GLOBAL APPEND PROPERTY extra_post_build_commands - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py - -o ${merged_hex_file} - ${generated_hex_file} - ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} - ) - set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${merged_hex_file}) endfunction() +get_property(version GLOBAL PROPERTY nrf_regtool_version) foreach(component IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS) - string(REGEX MATCH "(^.*):(.*$)" match ${component}) - set(operation "${CMAKE_MATCH_1}") - set(peripheral "${CMAKE_MATCH_2}") + if(component STREQUAL "GENERATE:UICR") + set(generated_hex_file ${PROJECT_BINARY_DIR}/uicr.hex) + if(version VERSION_GREATER_EQUAL 7.0.0) + nrf_regtool_generate_uicr(${generated_hex_file}) + else() + nrf_regtool_generate_peripheral(UICR ${generated_hex_file}) + endif() + + # UICR must be flashed together with the Zephyr binary. + set(merged_hex_file ${PROJECT_BINARY_DIR}/uicr_merged.hex) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${merged_hex_file} + ${generated_hex_file} + ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} + ) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${merged_hex_file}) - if(operation STREQUAL "GENERATE") - nrf_regtool_generate_hex_from_dts(${peripheral}) + elseif(component STREQUAL "GENERATE:BICR") + nrf_regtool_generate_peripheral(BICR ${PROJECT_BINARY_DIR}/bicr.hex) else() message(FATAL_ERROR "Unrecognized package component: \"${component}\"") endif() diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake index e147d1b0532..81345c1ae50 100644 --- a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake @@ -22,6 +22,7 @@ if(NRF_REGTOOL) "Found nrf-regtool (found suitable version \"${PACKAGE_VERSION}\", " "minimum required is \"${PACKAGE_FIND_VERSION}\")" ) + set_property(GLOBAL PROPERTY nrf_regtool_version ${PACKAGE_VERSION}) return() endif() endif() diff --git a/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index 2deb6756009..ad84324a3e9 100644 --- a/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -4,5 +4,5 @@ */ &cpuapp_ram0x_region { - perm-execute; + nordic,access = ; }; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpurad.overlay index 73ec4c1dc08..84edfb2b6f1 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpurad.overlay +++ b/tests/drivers/spi/spi_controller_peripheral/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -5,11 +5,6 @@ */ #include "nrf54h20dk_nrf54h20_common.dtsi" -/* Increase dma region to fit dmm heap. */ -&cpurad_dma_region { - reg = <0x1e80 0x100>; -}; - &spi130 { memory-regions = <&cpurad_dma_region>; }; diff --git a/tests/drivers/spi/spi_error_cases/boards/nrf54h20dk_nrf54h20_cpuppr_launcher.overlay b/tests/drivers/spi/spi_error_cases/boards/nrf54h20dk_nrf54h20_cpuppr_launcher.overlay index 6e30d173155..facf592d94c 100644 --- a/tests/drivers/spi/spi_error_cases/boards/nrf54h20dk_nrf54h20_cpuppr_launcher.overlay +++ b/tests/drivers/spi/spi_error_cases/boards/nrf54h20dk_nrf54h20_cpuppr_launcher.overlay @@ -14,10 +14,6 @@ interrupt-parent = <&cpuppr_clic>; }; -&shared_ram3x_region { - status = "okay"; -}; - &gpio0 { status = "reserved"; }; diff --git a/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54h20dk_nrf54h20_cpurad.overlay index 2bde29c9fc5..0ded983c2af 100644 --- a/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54h20dk_nrf54h20_cpurad.overlay +++ b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -2,11 +2,6 @@ #include "nrf54h20dk_nrf54h20_common.dtsi" -&cpurad_dma_region { - /* Default space is not enough. */ - reg = <0x1e80 0x100>; -}; - &dut { memory-regions = <&cpurad_dma_region>; };