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_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_CORTEXM35P config ARCH_CORTEXM35P
bool bool
@ -755,6 +756,7 @@ config ARCH_CORTEXM35P
select ARCH_HAVE_MEMFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_CORTEXM55 config ARCH_CORTEXM55
bool bool
@ -771,6 +773,7 @@ config ARCH_CORTEXM55
select ARCH_HAVE_MEMFAULT_DEBUG select ARCH_HAVE_MEMFAULT_DEBUG
select ARCH_HAVE_BUSFAULT_DEBUG select ARCH_HAVE_BUSFAULT_DEBUG
select ARCH_HAVE_USAGEFAULT_DEBUG select ARCH_HAVE_USAGEFAULT_DEBUG
select ARCH_HAVE_SECUREFAULT_DEBUG if ARCH_TRUSTZONE_SECURE
config ARCH_FAMILY config ARCH_FAMILY
string string
@ -1006,6 +1009,19 @@ config DEBUG_USAGEFAULT
output is sometimes helpful when debugging difficult usage fault problems, output is sometimes helpful when debugging difficult usage fault problems,
but may be more than you typically want to see. 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 config ARM_SEMIHOSTING_SYSLOG
bool "Semihosting SYSLOG support" bool "Semihosting SYSLOG support"
select ARCH_SYSLOG select ARCH_SYSLOG

View File

@ -34,6 +34,7 @@
#include "arm_arch.h" #include "arm_arch.h"
#include "nvic.h" #include "nvic.h"
#include "sau.h"
#include "arm_internal.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 hfsr = getreg32(NVIC_HFAULTS);
uint32_t cfsr = getreg32(NVIC_CFAULTS); uint32_t cfsr = getreg32(NVIC_CFAULTS);
#ifdef CONFIG_DEBUG_SECUREFAULT
uint32_t sfsr = getreg32(SAU_SFSR);
#endif /* CONFIG_DEBUG_SECUREFAULT */
UNUSED(cfsr); UNUSED(cfsr);
@ -146,6 +150,13 @@ int arm_hardfault(int irq, FAR void *context, FAR void *arg)
return arm_usagefault(irq, context, arg); return arm_usagefault(irq, context, arg);
} }
#endif /* CONFIG_DEBUG_USAGEFAULT */ #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 */ /* 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_NSC (1 << 1) /* Bit 1: Non-secure callable */
#define SAU_RLAR_LIMIT_MASK 0xffffffe0 /* Bits 5-31: Region limit address */ #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 * 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_memfault(int irq, FAR void *context, FAR void *arg);
int arm_busfault(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_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 */ # endif /* CONFIG_ARCH_CORTEXM3,4,7 */