cortex-m/hardfault: add secure-fault handler

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-12-21 16:34:42 +08:00 committed by Xiang Xiao
parent 6d165506d5
commit 2737701996
5 changed files with 160 additions and 0 deletions

View File

@ -739,6 +739,7 @@ config ARCH_CORTEXM33
select ARCH_HAVE_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_CORTEXM35P
bool
@ -755,6 +756,7 @@ config ARCH_CORTEXM35P
select ARCH_HAVE_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_CORTEXM55
bool
@ -771,6 +773,7 @@ config ARCH_CORTEXM55
select ARCH_HAVE_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_FAMILY
string
@ -1006,6 +1009,19 @@ config DEBUG_USAGEFAULT
output is sometimes helpful when debugging difficult usage fault problems,
but may be more than you typically want to see.
config ARCH_HAVE_SECUREFAULT_DEBUG
bool
default n
config DEBUG_SECUREFAULT
bool "Verbose Secure-Fault Debug"
default n
depends on ARCH_HAVE_SECUREFAULT_DEBUG && DEBUG_ALERT
---help---
Enables verbose debug output when a usage fault is occurs. This verbose
output is sometimes helpful when debugging difficult usage fault problems,
but may be more than you typically want to see.
config ARM_SEMIHOSTING_SYSLOG
bool "Semihosting SYSLOG support"
select ARCH_SYSLOG

View File

@ -34,6 +34,7 @@
#include "arm_arch.h"
#include "nvic.h"
#include "sau.h"
#include "arm_internal.h"
/****************************************************************************
@ -75,6 +76,9 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg)
{
uint32_t hfsr = getreg32(NVIC_HFAULTS);
uint32_t cfsr = getreg32(NVIC_CFAULTS);
#ifdef CONFIG_DEBUG_SECUREFAULT
uint32_t sfsr = getreg32(SAU_SFSR);
#endif /* CONFIG_DEBUG_SECUREFAULT */
UNUSED(cfsr);
@ -146,6 +150,13 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg)
return arm_usagefault(irq, context, arg);
}
#endif /* CONFIG_DEBUG_USAGEFAULT */
#ifdef CONFIG_DEBUG_SECUREFAULT
if (sfsr & SAU_SFSR_MASK)
{
return arm_securefault(irq, context, arg);
}
#endif /* CONFIG_DEBUG_SECUREFAULT */
}
/* Dump some hard fault info */

View File

@ -0,0 +1,119 @@
/****************************************************************************
* arch/arm/src/armv8-m/arm_securefault.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 <stdint.h>
#include <string.h>
#include <assert.h>
#include <debug.h>
#include <arch/irq.h>
#include "arm_arch.h"
#include "nvic.h"
#include "sau.h"
#include "arm_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_DEBUG_SECUREFAULT
# define sfalert(format, ...) _alert(format, ##__VA_ARGS__)
#else
# define sfalert(...)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: arm_securefault
*
* Description:
* This is Secure Fault exception handler. It also catches SVC call
* exceptions that are performed in bad contexts.
*
****************************************************************************/
int arm_securefault(int irq, FAR void *context, FAR void *arg)
{
uint32_t sfsr = getreg32(SAU_SFSR);
sfalert("PANIC!!! Secure Fault:\n");
sfalert("\tIRQ: %d regs: %p\n", irq, context);
sfalert("\tBASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
getbasepri(), getprimask(), getipsr(), getcontrol());
sfalert("\tCFSR: %08x HFSR: %08x DFSR: %08x\n", getreg32(NVIC_CFAULTS),
getreg32(NVIC_HFAULTS), getreg32(NVIC_DFAULTS));
sfalert("\tBFAR: %08x AFSR: %08x SFAR: %08x\n",
getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS),
getreg32(SAU_SFAR));
sfalert("Secure Fault Reason:\n");
if (sfsr & SAU_SFSR_INVEP)
{
sfalert("\tInvalid entry point\n");
}
if (sfsr & SAU_SFSR_INVIS)
{
sfalert("\tInvalid integrity signature\n");
}
if (sfsr & SAU_SFSR_INVER)
{
sfalert("\tInvalid exception return\n");
}
if (sfsr & SAU_SFSR_AUVIOL)
{
sfalert("\tAttribution unit violation\n");
}
if (sfsr & SAU_SFSR_INVTRAN)
{
sfalert("\tInvalid transition\n");
}
if (sfsr & SAU_SFSR_LSPERR)
{
sfalert("\tLazy state preservation\n");
}
if (sfsr & SAU_SFSR_LSERR)
{
sfalert("\tLazy state error\n");
}
/* clear SFSR sticky bits */
putreg32(0xff, SAU_SFSR);
up_irq_save();
PANIC();
return OK;
}

View File

@ -81,6 +81,19 @@
#define SAU_RLAR_NSC (1 << 1) /* Bit 1: Non-secure callable */
#define SAU_RLAR_LIMIT_MASK 0xffffffe0 /* Bits 5-31: Region limit address */
/* Secure Fault Status Register Definitions */
#define SAU_SFSR_MASK (0xf) /* Secure Fault Status Register Mask */
#define SAU_SFSR_INVEP (1 << 0) /* Bit 0: INVEP Mask */
#define SAU_SFSR_INVIS (1 << 1) /* Bit 1: INVIS Mask */
#define SAU_SFSR_INVER (1 << 2) /* Bit 2: INVER Mask */
#define SAU_SFSR_AUVIOL (1 << 3) /* Bit 3: AUVIOL Mask */
#define SAU_SFSR_INVTRAN (1 << 4) /* Bit 4: INVTRAN Mask */
#define SAU_SFSR_LSPERR (1 << 5) /* Bit 5: LSPERR Mask */
#define SAU_SFSR_SFARVALID (1 << 6) /* Bit 6: SFARVALID Mask */
#define SAU_SFSR_LSERR (1 << 7) /* Bit 7: LSERR Mask */
/****************************************************************************
* Public Function Prototypes
****************************************************************************/

View File

@ -345,6 +345,7 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg);
int arm_memfault(int irq, FAR void *context, FAR void *arg);
int arm_busfault(int irq, FAR void *context, FAR void *arg);
int arm_usagefault(int irq, FAR void *context, FAR void *arg);
int arm_securefault(int irq, FAR void *context, FAR void *arg);
# endif /* CONFIG_ARCH_CORTEXM3,4,7 */