cortex-m/hardfault: add secure-fault handler
Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
6d165506d5
commit
2737701996
@ -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
|
||||||
|
@ -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 */
|
||||||
|
119
arch/arm/src/armv8-m/arm_securefault.c
Normal file
119
arch/arm/src/armv8-m/arm_securefault.c
Normal 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;
|
||||||
|
}
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user