Branch data Line data Source code
1 : : /* 2 : : 3 : : Copyright (c) 2009-2021 ARM Limited. All rights reserved. 4 : : 5 : : SPDX-License-Identifier: Apache-2.0 6 : : 7 : : Licensed under the Apache License, Version 2.0 (the License); you may 8 : : not use this file except in compliance with the License. 9 : : You may obtain a copy of the License at 10 : : 11 : : www.apache.org/licenses/LICENSE-2.0 12 : : 13 : : Unless required by applicable law or agreed to in writing, software 14 : : distributed under the License is distributed on an AS IS BASIS, WITHOUT 15 : : WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 : : See the License for the specific language governing permissions and 17 : : limitations under the License. 18 : : 19 : : NOTICE: This file has been modified by Nordic Semiconductor ASA. 20 : : 21 : : */ 22 : : 23 : : /* NOTE: Template files (including this one) are application specific and therefore expected to 24 : : be copied into the application project folder prior to its use! */ 25 : : 26 : : #include <stdint.h> 27 : : #include <stdbool.h> 28 : : #include "nrf.h" 29 : : #include "nrf_peripherals.h" 30 : : #include "nrf53_erratas.h" 31 : : #include "system_nrf5340_application.h" 32 : : #include "system_nrf53_approtect.h" 33 : : 34 : : /*lint ++flb "Enter library region" */ 35 : : 36 : : void SystemStoreFICRNS(); 37 : : 38 : : /* NRF5340 application core uses a variable System Clock Frequency that starts at 64MHz */ 39 : : #define __SYSTEM_CLOCK_MAX (128000000UL) 40 : : #define __SYSTEM_CLOCK_INITIAL ( 64000000UL) 41 : : 42 : : #define TRACE_PIN_CNF_VALUE ( (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | \ 43 : : (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | \ 44 : : (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | \ 45 : : (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | \ 46 : : (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | \ 47 : : (GPIO_PIN_CNF_MCUSEL_TND << GPIO_PIN_CNF_MCUSEL_Pos)) 48 : : 49 : : #define TRACE_TRACECLK_PIN TAD_PSEL_TRACECLK_PIN_Traceclk 50 : : #define TRACE_TRACEDATA0_PIN TAD_PSEL_TRACEDATA0_PIN_Tracedata0 51 : : #define TRACE_TRACEDATA1_PIN TAD_PSEL_TRACEDATA1_PIN_Tracedata1 52 : : #define TRACE_TRACEDATA2_PIN TAD_PSEL_TRACEDATA2_PIN_Tracedata2 53 : : #define TRACE_TRACEDATA3_PIN TAD_PSEL_TRACEDATA3_PIN_Tracedata3 54 : : 55 : : #if defined ( __CC_ARM ) 56 : : uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL; 57 : : #elif defined ( __ICCARM__ ) 58 : : __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_INITIAL; 59 : : #elif defined ( __GNUC__ ) 60 : : uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_INITIAL; 61 : : #endif 62 : : 63 : 0 : void SystemCoreClockUpdate(void) 64 : : { 65 : : #if defined(NRF_TRUSTZONE_NONSECURE) 66 : : SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_NS->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk)); 67 : : #else 68 : 0 : SystemCoreClock = __SYSTEM_CLOCK_MAX >> (NRF_CLOCK_S->HFCLKCTRL & (CLOCK_HFCLKCTRL_HCLK_Msk)); 69 : : #endif 70 : 0 : } 71 : : 72 : 0 : void SystemInit(void) 73 : : { 74 : : #if !defined(NRF_TRUSTZONE_NONSECURE) 75 : : /* Perform Secure-mode initialization routines. */ 76 : : 77 : : /* Set all ARM SAU regions to NonSecure if TrustZone extensions are enabled. 78 : : * Nordic SPU should handle Secure Attribution tasks */ 79 : : #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 80 : : SAU->CTRL |= (1 << SAU_CTRL_ALLNS_Pos); 81 : : #endif 82 : : 83 : : /* Workaround for Errata 97 "ERASEPROTECT, APPROTECT, or startup problems" found at the Errata document 84 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 85 [ # # ]: 0 : if (nrf53_errata_97()) 86 : : { 87 [ # # ]: 0 : if (*((volatile uint32_t *)0x50004A20ul) == 0) 88 : : { 89 : 0 : *((volatile uint32_t *)0x50004A20ul) = 0xDul; 90 : 0 : *((volatile uint32_t *)0x5000491Cul) = 0x1ul; 91 : 0 : *((volatile uint32_t *)0x5000491Cul) = 0x0ul; 92 : : } 93 : : } 94 : : 95 : : /* Trimming of the device. Copy all the trimming values from FICR into the target addresses. Trim 96 : : until one ADDR is not initialized. */ 97 : 0 : uint32_t index = 0; 98 [ # # # # ]: 0 : for (index = 0; index < 32ul && NRF_FICR_S->TRIMCNF[index].ADDR != (uint32_t *)0xFFFFFFFFul; index++){ 99 : : #if defined ( __ICCARM__ ) 100 : : /* IAR will complain about the order of volatile pointer accesses. */ 101 : : #pragma diag_suppress=Pa082 102 : : #endif 103 : 0 : *((volatile uint32_t *)NRF_FICR_S->TRIMCNF[index].ADDR) = NRF_FICR_S->TRIMCNF[index].DATA; 104 : : #if defined ( __ICCARM__ ) 105 : : #pragma diag_default=Pa082 106 : : #endif 107 : : } 108 : : 109 : : /* errata 64 must be before errata 42, as errata 42 is dependant on the changes in errata 64*/ 110 : : /* Workaround for Errata 64 "VREGMAIN has invalid configuration when CPU is running at 128 MHz" found at the Errata document 111 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 112 [ # # ]: 0 : if (nrf53_errata_64()) 113 : : { 114 : 0 : *((volatile uint32_t *)0x5000470Cul) = 0x29ul; 115 : 0 : *((volatile uint32_t *)0x5000473Cul) = 0x3ul; 116 : : } 117 : : 118 : : /* Workaround for Errata 42 "Reset value of HFCLKCTRL is invalid" found at the Errata document 119 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 120 [ # # ]: 0 : if (nrf53_errata_42()) 121 : : { 122 : 0 : *((volatile uint32_t *)0x50039530ul) = 0xBEEF0044ul; 123 : 0 : NRF_CLOCK_S->HFCLKCTRL = CLOCK_HFCLKCTRL_HCLK_Div2 << CLOCK_HFCLKCTRL_HCLK_Pos; 124 : : } 125 : : 126 : : /* Workaround for Errata 46 "Higher power consumption of LFRC" found at the Errata document 127 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 128 [ # # ]: 0 : if (nrf53_errata_46()) 129 : : { 130 : 0 : *((volatile uint32_t *)0x5003254Cul) = 0; 131 : : } 132 : : 133 : : /* Workaround for Errata 49 "SLEEPENTER and SLEEPEXIT events asserted after pin reset" found at the Errata document 134 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 135 [ # # ]: 0 : if (nrf53_errata_49()) 136 : : { 137 [ # # ]: 0 : if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk) 138 : : { 139 : 0 : NRF_POWER_S->EVENTS_SLEEPENTER = 0; 140 : 0 : NRF_POWER_S->EVENTS_SLEEPEXIT = 0; 141 : : } 142 : : } 143 : : 144 : : /* Workaround for Errata 55 "Bits in RESETREAS are set when they should not be" found at the Errata document 145 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 146 [ # # ]: 0 : if (nrf53_errata_55()) 147 : : { 148 [ # # ]: 0 : if (NRF_RESET_S->RESETREAS & RESET_RESETREAS_RESETPIN_Msk){ 149 : 0 : NRF_RESET_S->RESETREAS = ~RESET_RESETREAS_RESETPIN_Msk; 150 : : } 151 : : } 152 : : 153 : : /* Workaround for Errata 69 "VREGMAIN configuration is not retained in System OFF" found at the Errata document 154 : : for your device located at https://infocenter.nordicsemi.com/index.jsp */ 155 [ # # ]: 0 : if (nrf53_errata_69()) 156 : : { 157 : 0 : *((volatile uint32_t *)0x5000470Cul) =0x65ul; 158 : : } 159 : : 160 : : #if !defined(NRF_SKIP_FICR_NS_COPY_TO_RAM) 161 : : SystemStoreFICRNS(); 162 : : #endif 163 : : 164 : : #if defined(CONFIG_NFCT_PINS_AS_GPIOS) 165 : : 166 : : if ((NRF_UICR_S->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) 167 : : { 168 : : NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 169 : : 170 : : while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy); 171 : : NRF_UICR_S->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; 172 : : 173 : : while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy); 174 : : NRF_NVMC_S->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 175 : : 176 : : while (NRF_NVMC_S->READY == NVMC_READY_READY_Busy); 177 : : NVIC_SystemReset(); 178 : : } 179 : : 180 : : #endif 181 : : 182 : : /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product 183 : : Specification to see which one). */ 184 : : #if defined (ENABLE_SWO) 185 : : // Enable Trace And Debug peripheral 186 : : NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk; 187 : : NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk; 188 : : 189 : : // Set up Trace pad SPU firewall 190 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN); 191 : : 192 : : // Configure trace port pad 193 : : NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE; 194 : : 195 : : // Select trace pin 196 : : NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN; 197 : : 198 : : // Set trace port speed to 64 MHz 199 : : NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz; 200 : : #endif 201 : : 202 : : /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product 203 : : Specification to see which ones). */ 204 : : #if defined (ENABLE_TRACE) 205 : : // Enable Trace And Debug peripheral 206 : : NRF_TAD_S->ENABLE = TAD_ENABLE_ENABLE_Msk; 207 : : NRF_TAD_S->CLOCKSTART = TAD_CLOCKSTART_START_Msk; 208 : : 209 : : // Set up Trace pads SPU firewall 210 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACECLK_PIN); 211 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA0_PIN); 212 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA1_PIN); 213 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA2_PIN); 214 : : NRF_SPU_S->GPIOPORT[0].PERM &= ~(1 << TRACE_TRACEDATA3_PIN); 215 : : 216 : : // Configure trace port pads 217 : : NRF_P0_S->PIN_CNF[TRACE_TRACECLK_PIN] = TRACE_PIN_CNF_VALUE; 218 : : NRF_P0_S->PIN_CNF[TRACE_TRACEDATA0_PIN] = TRACE_PIN_CNF_VALUE; 219 : : NRF_P0_S->PIN_CNF[TRACE_TRACEDATA1_PIN] = TRACE_PIN_CNF_VALUE; 220 : : NRF_P0_S->PIN_CNF[TRACE_TRACEDATA2_PIN] = TRACE_PIN_CNF_VALUE; 221 : : NRF_P0_S->PIN_CNF[TRACE_TRACEDATA3_PIN] = TRACE_PIN_CNF_VALUE; 222 : : 223 : : // Select trace pins 224 : : NRF_TAD_S->PSEL.TRACECLK = TRACE_TRACECLK_PIN; 225 : : NRF_TAD_S->PSEL.TRACEDATA0 = TRACE_TRACEDATA0_PIN; 226 : : NRF_TAD_S->PSEL.TRACEDATA1 = TRACE_TRACEDATA1_PIN; 227 : : NRF_TAD_S->PSEL.TRACEDATA2 = TRACE_TRACEDATA2_PIN; 228 : : NRF_TAD_S->PSEL.TRACEDATA3 = TRACE_TRACEDATA3_PIN; 229 : : 230 : : // Set trace port speed to 64 MHz 231 : : NRF_TAD_S->TRACEPORTSPEED = TAD_TRACEPORTSPEED_TRACEPORTSPEED_64MHz; 232 : : 233 : : #endif 234 : : 235 : : /* Allow Non-Secure code to run FPU instructions. 236 : : * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */ 237 : 0 : SCB->NSACR |= (3UL << 10); 238 : : 239 : : /* Handle fw-branch APPROTECT setup. */ 240 : 0 : nrf53_handle_approtect(); 241 : : 242 : : #endif 243 : : 244 : : /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the 245 : : * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit 246 : : * operations are not used in your code. */ 247 : : #if (__FPU_USED == 1) 248 : : SCB->CPACR |= (3UL << 20) | (3UL << 22); 249 : : __DSB(); 250 : : __ISB(); 251 : : #endif 252 : : 253 : 0 : SystemCoreClockUpdate(); 254 : 0 : } 255 : : 256 : : /* Workaround to allow NS code to access FICR. Override NRF_FICR_NS to move FICR_NS buffer. */ 257 : : #define FICR_SIZE 0x1000ul 258 : : #define RAM_BASE 0x20000000ul 259 : : #define RAM_END 0x2FFFFFFFul 260 : : 261 : : /* Copy FICR_S to FICR_NS RAM region */ 262 : 0 : void SystemStoreFICRNS() 263 : : { 264 : : if ((uint32_t)NRF_FICR_NS < RAM_BASE || (uint32_t)NRF_FICR_NS + FICR_SIZE > RAM_END) 265 : : { 266 : : /* FICR_NS is not in RAM. */ 267 : : return; 268 : : } 269 : : /* Copy FICR to NS-accessible RAM block. */ 270 : 0 : volatile uint32_t * from = (volatile uint32_t *)((uint32_t)NRF_FICR_S + (FICR_SIZE - sizeof(uint32_t))); 271 : 0 : volatile uint32_t * to = (volatile uint32_t *)((uint32_t)NRF_FICR_NS + (FICR_SIZE - sizeof(uint32_t))); 272 : 0 : volatile uint32_t * copy_from_end = (volatile uint32_t *)NRF_FICR_S; 273 [ # # ]: 0 : while (from >= copy_from_end) 274 : : { 275 : 0 : *(to--) = *(from--); 276 : : } 277 : : 278 : : /* Make RAM region NS. */ 279 : 0 : uint32_t ram_region = ((uint32_t)NRF_FICR_NS - (uint32_t)RAM_BASE) / SPU_RAMREGION_SIZE; 280 : 0 : NRF_SPU_S->RAMREGION[ram_region].PERM &= ~(1 << SPU_RAMREGION_PERM_SECATTR_Pos); 281 : : } 282 : : 283 : : /* Block write and execute access to FICR RAM region */ 284 : 0 : void SystemLockFICRNS() 285 : : { 286 : : if ((uint32_t)NRF_FICR_NS < RAM_BASE || (uint32_t)NRF_FICR_NS + FICR_SIZE > RAM_END) 287 : : { 288 : : /* FICR_NS is not in RAM. */ 289 : : return; 290 : : } 291 : : 292 : 0 : uint32_t ram_region = ((uint32_t)NRF_FICR_NS - (uint32_t)RAM_BASE) / SPU_RAMREGION_SIZE; 293 : 0 : NRF_SPU_S->RAMREGION[ram_region].PERM &= 294 : : ~( 295 : : (1 << SPU_RAMREGION_PERM_WRITE_Pos) | 296 : : (1 << SPU_RAMREGION_PERM_EXECUTE_Pos) 297 : : ); 298 : 0 : NRF_SPU_S->RAMREGION[ram_region].PERM |= 1 << SPU_RAMREGION_PERM_LOCK_Pos; 299 : : } 300 : : 301 : : /*lint --flb "Leave library region" */