diff --git a/arch/arm/src/nrf91/Kconfig b/arch/arm/src/nrf91/Kconfig index 23dd45ca7bb..53c535b605f 100644 --- a/arch/arm/src/nrf91/Kconfig +++ b/arch/arm/src/nrf91/Kconfig @@ -37,10 +37,30 @@ config NRF91_CPUAPP_MEM_FLASH_SIZE hex default 0x100000 if NRF91_CPUAPP_MEM_FLASH_1024 +if !ARCH_TRUSTZONE_NONSECURE + config NRF91_ENABLE_APPROTECT bool "nRF91 enable APPROTECT" default n +config NRF91_UICR_HFXO_WORKAROUND + bool "nRF91 enable UICR HFXO workaround" + default y + +config NRF91_LFXO_ERRATA31_WORKAROUND + bool "nRF91 enable LFXO errata 31 workaround" + default y + +config NRF91_DCDC_ERRATA15_WORKAROUND + bool "nRF91 enable DCDC errata 15 workaround" + default y + +endif # !ARCH_TRUSTZONE_NONSECURE + +config NRF91_FICR_NS_WORKAROUND + bool "nRF91 access to FICR in non-secure environment" + default y + # Peripheral Selection config NRF91_I2C_MASTER @@ -319,6 +339,17 @@ endif # NRF91_CONFIG_NONSECURE endmenu # "SPU configuration" +config NRF91_NONSECURE_RAM_FICR_OFFSET + hex + default 0x1000 + +config NRF91_NONSECURE_RAM_FICR + bool "Support for non-secure FICR in RAM" + default n + ---help--- + Support for non-secure FICR in RAM. + The last page 4KiB of the RAM is recerved for this. + menu "Clock Configuration" config NRF91_HFCLK_XTAL diff --git a/arch/arm/src/nrf91/Make.defs b/arch/arm/src/nrf91/Make.defs index 224c2f7efa0..3c395277470 100644 --- a/arch/arm/src/nrf91/Make.defs +++ b/arch/arm/src/nrf91/Make.defs @@ -30,7 +30,7 @@ endif CHIP_CSRCS += nrf91_start.c nrf91_clockconfig.c nrf91_irq.c nrf91_utils.c CHIP_CSRCS += nrf91_allocateheap.c nrf91_lowputc.c nrf91_gpio.c -CHIP_CSRCS += nrf91_uid.c nrf91_spu.c +CHIP_CSRCS += nrf91_uid.c nrf91_spu.c nrf91_errata.c ifeq ($(CONFIG_NRF91_PROGMEM),y) CHIP_CSRCS += nrf91_flash.c diff --git a/arch/arm/src/nrf91/hardware/nrf91_ficr.h b/arch/arm/src/nrf91/hardware/nrf91_ficr.h index 97bd79a14da..2fba1795249 100644 --- a/arch/arm/src/nrf91/hardware/nrf91_ficr.h +++ b/arch/arm/src/nrf91/hardware/nrf91_ficr.h @@ -44,6 +44,8 @@ #define NRF91_FICR_INFO_DEVICETYPE_OFFSET 0x228 /* Device type */ /* TODO */ +#define NRF91_FICR_LAST_OFFSET 0xc1c + /* FICR Register Addresses *************************************************/ #define NRF91_FICR_INFO_DEVICEID0 (NRF91_FICR_BASE + NRF91_FICR_INFO_DEVICEID0_OFFSET) diff --git a/arch/arm/src/nrf91/hardware/nrf91_memorymap.h b/arch/arm/src/nrf91/hardware/nrf91_memorymap.h index 3671f206160..3a32f3f1484 100644 --- a/arch/arm/src/nrf91/hardware/nrf91_memorymap.h +++ b/arch/arm/src/nrf91/hardware/nrf91_memorymap.h @@ -46,6 +46,13 @@ # define NRF91_NS(x) (x) #endif +/* Non-secure FICR */ + +#define NRF91_NONSECURE_RAM_FICR_OFFSET 0x1000 +#define NRF91_NONSECURE_RAM_FICR (NRF91_SRAM_BASE + \ + CONFIG_NRF91_CPUAPP_MEM_RAM_SIZE \ + - NRF91_NONSECURE_RAM_FICR_OFFSET) + /* APB Peripherals */ #ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE @@ -112,7 +119,13 @@ # define NRF91_CRYPTOCELL_BASE 0x50840000 #endif #define NRF91_GPIO_P0_BASE NRF91_NS(0x50842500) -#define NRF91_FICR_BASE 0x00FF0000 +#ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE +# define NRF91_FICR_BASE 0x00FF0000 +#elif CONFIG_NRF91_FICR_NS_WORKAROUND +/* Non-secure FICR RAM copy */ + +# define NRF91_FICR_BASE NRF91_NONSECURE_RAM_FICR +#endif #define NRF91_UICR_BASE 0x00FF8000 #define NRF91_TAD_BASE 0xE0080000 diff --git a/arch/arm/src/nrf91/hardware/nrf91_regulators.h b/arch/arm/src/nrf91/hardware/nrf91_regulators.h new file mode 100644 index 00000000000..74d9c14f1ce --- /dev/null +++ b/arch/arm/src/nrf91/hardware/nrf91_regulators.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * arch/arm/src/nrf91/hardware/nrf91_regulators.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NRF91_HARDWARE_NRF91_REGULATORS_H +#define __ARCH_ARM_SRC_NRF91_HARDWARE_NRF91_REGULATORS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "nrf91_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +#define NRF91_REGULATORS_SYSTEMOFF_OFFSET 0x500 /* System OFF register */ +#define NRF91_REGULATORS_EXTPOFCON_OFFSET 0x514 /* External power failure warning configuration */ +#define NRF91_REGULATORS_DCDCEN_OFFSET 0x578 /* Enable DC/DC mode of the main voltage regulator */ + +/* Register definitions *****************************************************/ + +#define NRF91_REGULATORS_SYSTEMOFF (NRF91_REGULATORS_BASE + NRF91_REGULATORS_SYSTEMOFF_OFFSET) +#define NRF91_REGULATORS_EXTPOFCON (NRF91_REGULATORS_BASE + NRF91_REGULATORS_EXTPOFCON_OFFSET) +#define NRF91_REGULATORS_DCDCEN (NRF91_REGULATORS_BASE + NRF91_REGULATORS_DCDCEN_OFFSET) + +/* Register bit definitions *************************************************/ + +#define REGULATORS_DCDCEN_ENABLE (1 << 0) + +#endif /* __ARCH_ARM_SRC_NRF91_HARDWARE_NRF91_REGULATORS_H */ diff --git a/arch/arm/src/nrf91/nrf91_errata.c b/arch/arm/src/nrf91/nrf91_errata.c new file mode 100644 index 00000000000..6a87e89ca55 --- /dev/null +++ b/arch/arm/src/nrf91/nrf91_errata.c @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/arm/src/nrf91/nrf91_errata.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "arm_internal.h" +#include "barriers.h" + +#include "hardware/nrf91_memorymap.h" +#include "hardware/nrf91_regulators.h" +#include "hardware/nrf91_uicr.h" +#include "hardware/nrf91_ficr.h" +#include "hardware/nrf91_nvmc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MEMORY_SYNC() ARM_ISB(); ARM_DSB() + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_NRF91_UICR_HFXO_WORKAROUND +/**************************************************************************** + * Name: nrf91_uicr_recover + * + * Description: + * Recover HFXOCNT and HFXOSRC registers after erasing all FLASH. + * Without this workaround, the modem core never boots properly. + * + ****************************************************************************/ + +void nrf91_uicr_recover(void) +{ + bool hfxosrc_recover = false; + bool hfxocnt_recover = false; + + if (getreg32(NRF91_UICR_HFXOCNT) == 0xffffffff) + { + hfxocnt_recover = true; + } + + if (getreg32(NRF91_UICR_HFXOSRC) == 0xffffffff) + { + hfxosrc_recover = true; + } + + if (!hfxocnt_recover && !hfxosrc_recover) + { + return; + } + + /* Wait for flash */ + + while (!(getreg32(NRF91_NVMC_READY) & NVMC_READY_READY)) + { + } + + /* Enable write */ + + putreg32(NVMC_CONFIG_WEN, NRF91_NVMC_CONFIG); + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Write HFXOSRC */ + + if (hfxosrc_recover) + { + putreg32(0x0 , NRF91_UICR_HFXOSRC); + } + + /* Wait for flash */ + + while (!(getreg32(NRF91_NVMC_READY) & NVMC_READY_READY)) + { + } + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Write HFXOCNT */ + + if (hfxocnt_recover) + { + putreg32(0x20, NRF91_UICR_HFXOCNT); + } + + /* Wait for flash */ + + while (!(getreg32(NRF91_NVMC_READY) & NVMC_READY_READY)) + { + } + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Read only access */ + + putreg32(NVMC_CONFIG_REN, NRF91_NVMC_CONFIG); + + /* System reset */ + + up_systemreset(); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE +/**************************************************************************** + * Name: nrf91_errata_secure + * + * Description: + * Errata that must be applied in asecure environment + * + ****************************************************************************/ + +void nrf91_errata_secure(void) +{ +#ifdef NRF91_DCDC_ERRATA15_WORKAROUND + /* Workaround for 3.7 [15] REGULATORS: Supply regulators default to + * LDO mode after reset + */ + + putreg32(REGULATORS_DCDCEN_ENABLE, NRF91_REGULATORS_DCDCEN); +#endif + +#ifdef NRF91_LFXO_ERRATA31_WORKAROUND + /* Workaround for 3.15 [31] LFXO: LFXO startup fails */ + + *((volatile uint32_t *)0x5000470c) = 0x0; + *((volatile uint32_t *)0x50004710) = 0x1; +#endif + +#ifdef CONFIG_NRF91_UICR_HFXO_WORKAROUND + nrf91_uicr_recover(); +#endif +} + +/**************************************************************************** + * Name: nrf91_ficr_ram_copy + * + * Description: + * Copy FICR to a fixed RAM region. + * + ****************************************************************************/ + +void nrf91_ficr_ram_copy(void) +{ + const uint32_t *src; + uint32_t *dest; + + for (src = (const uint32_t *)NRF91_FICR_BASE, + dest = (uint32_t *)(NRF91_NONSECURE_RAM_FICR); + dest < (uint32_t *)(NRF91_SRAM_BASE + + CONFIG_NRF91_CPUAPP_MEM_RAM_SIZE); + ) + { + *dest++ = *src++; + } + + /* TODO: make RAM FICR read-only */ +} +#endif diff --git a/arch/arm/src/nrf91/nrf91_errata.h b/arch/arm/src/nrf91/nrf91_errata.h new file mode 100644 index 00000000000..0f04a0f2d91 --- /dev/null +++ b/arch/arm/src/nrf91/nrf91_errata.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * arch/arm/src/nrf91/nrf91_errata.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_NRF91_NRF91_ERRATA_H +#define __ARCH_ARM_SRC_NRF91_NRF91_ERRATA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE +/**************************************************************************** + * Name: nrf91_errata_secure + ****************************************************************************/ + +void nrf91_errata_secure(void); + +/**************************************************************************** + * Name: nrf91_ficr_ram_copy + ****************************************************************************/ + +void nrf91_ficr_ram_copy(void); +#endif + +#endif /* __ARCH_ARM_SRC_NRF91_NRF91_ERRATA_H */ diff --git a/arch/arm/src/nrf91/nrf91_start.c b/arch/arm/src/nrf91/nrf91_start.c index 2572ece7717..6776b2d69d8 100644 --- a/arch/arm/src/nrf91/nrf91_start.c +++ b/arch/arm/src/nrf91/nrf91_start.c @@ -44,6 +44,7 @@ #include "nrf91_gpio.h" #include "nrf91_serial.h" #ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE +# include "nrf91_errata.h" # include "nrf91_spu.h" #endif @@ -75,6 +76,7 @@ void __start(void) noinstrument_function; #endif +#ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE /**************************************************************************** * Name: nrf91_approtect ****************************************************************************/ @@ -83,6 +85,7 @@ static void nrf91_approtect(void) { /* TODO: missing logic */ } +#endif #ifdef CONFIG_NRF91_FLASH_PREFETCH /**************************************************************************** @@ -167,10 +170,20 @@ void __start(void) __asm__ __volatile__ ("\tcpsid i\n"); #ifndef CONFIG_ARCH_TRUSTZONE_NONSECURE + /* Apply errata */ + + nrf91_errata_secure(); + /* Handle APPROTECT configuration */ nrf91_approtect(); +# ifdef CONFIG_NRF91_FICR_NS_WORKAROUND + /* Copy FICR */ + + nrf91_ficr_ram_copy(); +# endif + /* Configure SPU */ nrf91_spu_configure(); diff --git a/boards/arm/nrf91/common/scripts/flash_app.ld b/boards/arm/nrf91/common/scripts/flash_app.ld index 2a237e1f13d..e8ca68d6cbf 100644 --- a/boards/arm/nrf91/common/scripts/flash_app.ld +++ b/boards/arm/nrf91/common/scripts/flash_app.ld @@ -20,6 +20,8 @@ #include +#include + /* CONFIG_RAM_SIZE includes SHMEM and FIRC_RAM */ #if CONFIG_RAM_SIZE > CONFIG_NRF91_CPUAPP_MEM_RAM_SIZE @@ -34,6 +36,15 @@ # define NRF91_SHMEM_SIZE (0) #endif +/* Non-secure FICR RAM copy - this must match */ + +#if defined(CONFIG_NRF91_NONSECURE_RAM_FICR_OFFSET) && \ + defined(CONFIG_ARCH_TRUSTZONE_NONSECURE) +# define FICR_RAM_SIZE (NRF91_NONSECURE_RAM_FICR_OFFSET) +#else +# define FICR_RAM_SIZE (0) +#endif + /* FLASH and RAM start */ #define FLASH_CPUAPP_START_ADDR (0x00000000) @@ -60,7 +71,7 @@ MEMORY progmem (rx) : ORIGIN = FLASH_CPUAPP_START_ADDR + FLASH_OFFSET, LENGTH = FLASH_IMG_SIZE datamem (rwx) : ORIGIN = RAM_CPUAPP_START_ADDR, - LENGTH = CONFIG_RAM_SIZE - NRF91_SHMEM_SIZE + LENGTH = CONFIG_RAM_SIZE - NRF91_SHMEM_SIZE - FICR_RAM_SIZE } OUTPUT_ARCH(arm)