arch/nrf91: add errata workarounds

This commit is contained in:
raiden00pl 2023-07-08 12:06:49 +02:00 committed by Alan Carvalho de Assis
parent 1af1ef4a89
commit 872a05911e
9 changed files with 365 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 <nuttx/config.h>
#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 */

View File

@ -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 <nuttx/config.h>
#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

View File

@ -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 <nuttx/config.h>
/****************************************************************************
* 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 */

View File

@ -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();

View File

@ -20,6 +20,8 @@
#include <nuttx/config.h>
#include <hardware/nrf91_memorymap.h>
/* 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)