Skip to content

Commit

Permalink
[nrf noup] Add MPC and SPC error reporting for nrf54l
Browse files Browse the repository at this point in the history
fixup! [nrf noup] platform: nordic_nrf: Add support for 54l

Adds handling of MPC and SPC errors.

Signed-off-by: Vidar Lillebø <vidar.lillebo@nordicsemi.no>
  • Loading branch information
vili-nordic authored and mswarowsky committed May 15, 2024
1 parent 016b1dd commit dd01147
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 43 deletions.
80 changes: 75 additions & 5 deletions platform/ext/target/nordic_nrf/common/core/faults.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ void SPU_Handler(void)
/* Clear SPU interrupt flag and pending SPU IRQ */
spu_clear_events();

#ifdef SPU_IRQn
NVIC_ClearPendingIRQ(SPU_IRQn);
#else
// TODO: NCSDK-25011: Support nrf54l
#endif
NVIC_ClearPendingIRQ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) - NVIC_USER_IRQ_OFFSET);

tfm_core_panic();
}
Expand All @@ -40,3 +36,77 @@ __attribute__((naked)) void SPU_IRQHandler(void)
"B . \n"
);
}

#ifdef NRF_SPU00
__attribute__((naked)) void SPU00_IRQHandler(void)
{
EXCEPTION_INFO();

__ASM volatile(
"BL SPU_Handler \n"
"B . \n"
);
}
#endif

#ifdef NRF_SPU10
__attribute__((naked)) void SPU10_IRQHandler(void)
{
EXCEPTION_INFO();

__ASM volatile(
"BL SPU_Handler \n"
"B . \n"
);
}
#endif

#ifdef NRF_SPU20
__attribute__((naked)) void SPU20_IRQHandler(void)
{
EXCEPTION_INFO();

__ASM volatile(
"BL SPU_Handler \n"
"B . \n"
);
}
#endif

#ifdef NRF_SPU30
__attribute__((naked)) void SPU30_IRQHandler(void)
{
EXCEPTION_INFO();

__ASM volatile(
"BL SPU_Handler \n"
"B . \n"
);
}
#endif

#ifdef NRF_MPC00
void MPC_Handler(void)
{
#ifdef TFM_EXCEPTION_INFO_DUMP
nrf_exception_info_store_context();
#endif

/* Clear MPC interrupt flag and pending MPC IRQ */
mpc_clear_events();

NVIC_ClearPendingIRQ(MPC00_IRQn);

tfm_core_panic();
}

__attribute__((naked)) void MPC00_IRQHandler(void)
{
EXCEPTION_INFO();

__ASM volatile(
"BL MPC_Handler \n"
"B . \n"
);
}
#endif
61 changes: 51 additions & 10 deletions platform/ext/target/nordic_nrf/common/core/native_drivers/spu.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,47 @@ uint32_t spu_events_get(void)
{
uint32_t events = 0;

for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) {
if(nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_PERIPHACCERR)){
events |= SPU_EVENT_PERIPHACCERR;
}
#if NRF_SPU_HAS_MEMORY
if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) {
events |= SPU_EVENT_RAMACCERR;
}
if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) {
events |= SPU_EVENT_FLASHACCERR;
if (nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_RAMACCERR)) {
events |= SPU_EVENT_RAMACCERR;
}
if (nrf_spu_event_check(spu_instances[i], NRF_SPU_EVENT_FLASHACCERR)) {
events |= SPU_EVENT_FLASHACCERR;
}
#endif /* NRF_SPU_HAS_MEMORY */
}
if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) {
events |= SPU_EVENT_PERIPHACCERR;

return events;
}

#ifdef MPC_PRESENT
void mpc_enable_interrupts(void)
{
uint32_t mask = NRF_MPC_INT_MEMACCERR_MASK;
nrf_mpc_int_enable(NRF_MPC00, mask);
}

uint32_t mpc_events_get(void)
{
uint32_t events = 0;

if (nrf_mpc_event_check(NRF_MPC00, NRF_MPC_EVENT_MEMACCERR)){
events |= MPC_EVENT_MEMACCERR;
}
#else
// TODO: NCSDK-25011: Support fault handling on 54L
#endif

return events;
}

void mpc_clear_events()
{
nrf_mpc_event_clear(NRF_MPC00, NRF_MPC_EVENT_MEMACCERR);
}
#endif /* MPC_PRESENT */

void spu_clear_events(void)
{
for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) {
Expand All @@ -158,6 +182,23 @@ void spu_clear_events(void)
}
}

#ifdef SPU_PERIPHACCERR_ADDRESS_ADDRESS_Msk
uint32_t spu_get_peri_addr(void) {
uint32_t addr = 0;

for(int i = 0; i < ARRAY_SIZE(spu_instances); i++) {
if(spu_instances[i]->EVENTS_PERIPHACCERR){
/* Only the lower 16 bits of the address are captured into the register. The upper
* 16 bits correspond to the upper 16 bits of the SPU's base address.
*/
addr = spu_instances[i]->PERIPHACCERR.ADDRESS | ((uint32_t)spu_instances[i] & 0xFFFF0000);
}
}

return addr;
}
#endif

#if NRF_SPU_HAS_MEMORY
void spu_regions_reset_unlocked_secure(void)
{
Expand Down
31 changes: 31 additions & 0 deletions platform/ext/target/nordic_nrf/common/core/native_drivers/spu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <nrfx.h>

#include <hal/nrf_spu.h>
#ifdef MPC_PRESENT
#include <hal/nrf_mpc.h>
#endif

#define SPU_LOCK_CONF_LOCKED true
#define SPU_LOCK_CONF_UNLOCKED false
Expand Down Expand Up @@ -58,6 +62,7 @@ enum spu_events {
SPU_EVENT_RAMACCERR = 1 << 0,
SPU_EVENT_FLASHACCERR = 1 << 1,
SPU_EVENT_PERIPHACCERR= 1 << 2,
MPC_EVENT_MEMACCERR = 1 << 3
};

/**
Expand Down Expand Up @@ -139,6 +144,12 @@ void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock);
*/
void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock);

/**
* /brief Retrieve the address of the transaction that triggered PERIPHACCERR.
*
*/
uint32_t spu_get_peri_addr(void);

/**
* \brief Return base address of a Flash SPU regions
*
Expand Down Expand Up @@ -225,4 +236,24 @@ uint32_t spu_regions_sram_get_last_id(void);
*/
uint32_t spu_regions_sram_get_region_size(void);

/**
* \brief MPC interrupt enabling
*
* Enable security violations outside the Cortex-M33
* to trigger SPU interrupts.
*/
void mpc_enable_interrupts(void);

/**
* \brief Retrieve bitmask of MPC events.
*/
uint32_t mpc_events_get(void);

/**
* \brief MPC event clearing
*
* Clear MPC event registers
*/
void mpc_clear_events(void);

#endif
46 changes: 36 additions & 10 deletions platform/ext/target/nordic_nrf/common/core/nrf_exception_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,60 @@

static struct nrf_exception_info nrf_exc_info;

static void spu_dump_context(struct nrf_exception_info *ctx)
static void dump_exception_info(struct nrf_exception_info *ctx)
{
SPMLOG_ERRMSG("Platform Exception: SPU Fault\r\n");
SPMLOG_ERRMSG("Platform Exception:\r\n");

#ifdef NRF_SPU
/* Report which type of violation occured */
if (ctx->events & SPU_EVENT_RAMACCERR) {
SPMLOG_DBGMSG(" RAMACCERR\r\n");
SPMLOG_DBGMSG(" SPU.RAMACCERR\r\n");
}

if (ctx->events & SPU_EVENT_PERIPHACCERR) {
SPMLOG_DBGMSG(" PERIPHACCERR\r\n");
SPMLOG_DBGMSG(" SPU.PERIPHACCERR\r\n");
SPMLOG_DBGMSGVAL(" Target addr: ", ctx->periphaccerr.address);
}

if (ctx->events & SPU_EVENT_FLASHACCERR) {
SPMLOG_DBGMSG(" FLASHACCERR\r\n");
SPMLOG_DBGMSG(" SPU.FLASHACCERR\r\n");
}
#else
// TODO: NCSDK-25011: Support error handling on nrf54l
#endif

#if MPC_PRESENT
if (ctx->events & MPC_EVENT_MEMACCERR) {
SPMLOG_DBGMSG(" MPC.MEMACCERR\r\n");
SPMLOG_DBGMSGVAL(" Target addr: ", ctx->memaccerr.address);
SPMLOG_DBGMSGVAL(" Access information: ", ctx->memaccerr.info);
SPMLOG_DBGMSGVAL(" Owner id: ", ctx->memaccerr.info & 0xf);
SPMLOG_DBGMSGVAL(" Masterport: ", (ctx->memaccerr.info & 0x1f0) >> 4);
SPMLOG_DBGMSGVAL(" Read: ", (ctx->memaccerr.info >> 12) & 1);
SPMLOG_DBGMSGVAL(" Write: ", (ctx->memaccerr.info >> 13) & 1);
SPMLOG_DBGMSGVAL(" Execute: ", (ctx->memaccerr.info >> 14) & 1);
SPMLOG_DBGMSGVAL(" Secure: ", (ctx->memaccerr.info >> 15) & 1);
SPMLOG_DBGMSGVAL(" Error source: ", (ctx->memaccerr.info >> 16) & 1);
}
#endif
}

void nrf_exception_info_store_context(void)
{
nrf_exc_info.events = spu_events_get();

spu_dump_context(&nrf_exc_info);
#ifdef SPU_PERIPHACCERR_ADDRESS_ADDRESS_Msk
if (nrf_exc_info.events & SPU_EVENT_PERIPHACCERR){
nrf_exc_info.periphaccerr.address = spu_get_peri_addr();
}
#endif

#ifdef MPC_PRESENT
nrf_exc_info.events |= mpc_events_get();
if (nrf_exc_info.events & MPC_EVENT_MEMACCERR)
{
nrf_exc_info.memaccerr.address = NRF_MPC00->MEMACCERR.ADDRESS;
nrf_exc_info.memaccerr.info = NRF_MPC00->MEMACCERR.INFO;
}
#endif

dump_exception_info(&nrf_exc_info);
}

void nrf_exception_info_get_context(struct nrf_exception_info *ctx)
Expand Down
10 changes: 10 additions & 0 deletions platform/ext/target/nordic_nrf/common/core/nrf_exception_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@

struct nrf_exception_info {
uint32_t events;
union{
struct {
uint32_t address;
} periphaccerr;

struct {
uint32_t address;
uint32_t info;
} memaccerr;
};
};

void nrf_exception_info_store_context(void);
Expand Down
2 changes: 2 additions & 0 deletions platform/ext/target/nordic_nrf/common/core/startup.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ void SPU10_IRQHandler(void);
void SPU20_IRQHandler(void);
void SPU30_IRQHandler(void);

void MPC00_IRQHandler(void);

void CRACEN_IRQHandler(void);

/*
Expand Down
27 changes: 14 additions & 13 deletions platform/ext/target/nordic_nrf/common/core/startup_nrf54l15.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,18 @@ DEFAULT_IRQ_HANDLER(GPIOTE30_1_Handler)
DEFAULT_IRQ_HANDLER(CLOCK_POWER_Handler)

#if defined(DOMAIN_NS) || defined(BL2)
DEFAULT_IRQ_HANDLER(SPU00_Handler)
DEFAULT_IRQ_HANDLER(SPU10_Handler)
DEFAULT_IRQ_HANDLER(SPU20_Handler)
DEFAULT_IRQ_HANDLER(SPU30_Handler)
DEFAULT_IRQ_HANDLER(MPC00_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU00_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU10_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU20_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU30_IRQHandler)
DEFAULT_IRQ_HANDLER(CRACEN_IRQHandler)
#else
// TODO: Move into the SPU error handling code
DEFAULT_IRQ_HANDLER(SPU00_Handler)
DEFAULT_IRQ_HANDLER(SPU10_Handler)
DEFAULT_IRQ_HANDLER(SPU20_Handler)
DEFAULT_IRQ_HANDLER(SPU30_Handler)
DEFAULT_IRQ_HANDLER(SPU00_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU10_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU20_IRQHandler)
DEFAULT_IRQ_HANDLER(SPU30_IRQHandler)
#endif

#if defined ( __GNUC__ )
Expand Down Expand Up @@ -213,8 +214,8 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
SPU00_Handler,
MPC00_Handler,
SPU00_IRQHandler,
MPC00_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
Expand Down Expand Up @@ -277,7 +278,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
SPU10_Handler,
SPU10_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
Expand Down Expand Up @@ -341,7 +342,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
SPU20_Handler,
SPU20_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
Expand Down Expand Up @@ -405,7 +406,7 @@ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
SPU30_Handler,
SPU30_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
default_tfm_IRQHandler,
Expand Down

0 comments on commit dd01147

Please sign in to comment.