Merge "Merge arm branch into master"
This commit is contained in:
commit
110df98619
58 changed files with 1532 additions and 2977 deletions
|
@ -6,6 +6,6 @@ ccflags-y +=-I$(srctree)/include/
|
|||
asflags-y = $(ccflags-y)
|
||||
|
||||
obj-y = vector_table.o reset.o \
|
||||
nmi_on_reset.o prep_c.o scs.o scb.o nmi.o \
|
||||
nmi_on_reset.o prep_c.o scb.o nmi.o \
|
||||
exc_manage.o
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief ARM CORTEX-M Series System Control Space
|
||||
*
|
||||
* Most of the SCS interface consists of simple bit-flipping methods, and is
|
||||
* implemented as inline functions in scs.h. This module thus contains only data
|
||||
* definitions and more complex routines, if needed.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <toolchain.h>
|
||||
#include <sections.h>
|
||||
|
||||
/* the linker always puts this object at 0xe000e000 */
|
||||
volatile struct __scs __scs_section __scs;
|
|
@ -64,33 +64,32 @@ void _FaultDump(const NANO_ESF *esf, int fault)
|
|||
int escalation = 0;
|
||||
|
||||
if (3 == fault) { /* hard fault */
|
||||
escalation = _ScbHardFaultIsForced();
|
||||
escalation = SCB->HFSR & SCB_HFSR_FORCED_Msk;
|
||||
PR_EXC("HARD FAULT: %s\n",
|
||||
escalation ? "Escalation (see below)!"
|
||||
: "Bus fault on vector table read\n");
|
||||
}
|
||||
|
||||
PR_EXC("MMFSR: 0x%" PRIx32 ", BFSR: 0x%" PRIx32 ", UFSR: 0x%"
|
||||
PRIx32 "\n",
|
||||
__scs.scb.cfsr.byte.mmfsr.val,
|
||||
__scs.scb.cfsr.byte.bfsr.val,
|
||||
__scs.scb.cfsr.byte.ufsr.val);
|
||||
PRIx32 "\n", SCB_MMFSR, SCB_BFSR, SCB_MMFSR);
|
||||
|
||||
if (_ScbMemFaultIsMmfarValid()) {
|
||||
PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet());
|
||||
if (SCB->CFSR & CFSR_MMARVALID_Msk) {
|
||||
PR_EXC("MMFAR: 0x%" PRIx32 "\n", SCB->MMFAR);
|
||||
if (escalation) {
|
||||
_ScbMemFaultMmfarReset();
|
||||
/* clear MMAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
|
||||
}
|
||||
}
|
||||
if (_ScbBusFaultIsBfarValid()) {
|
||||
PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet());
|
||||
if (SCB->CFSR & CFSR_BFARVALID_Msk) {
|
||||
PR_EXC("BFAR: 0x%" PRIx32 "\n", SCB->BFAR);
|
||||
if (escalation) {
|
||||
_ScbBusFaultBfarReset();
|
||||
/* clear CFSR_BFAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear USFR sticky bits */
|
||||
_ScbUsageFaultAllFaultsReset();
|
||||
SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk;
|
||||
#else
|
||||
#error Unknown ARM architecture
|
||||
#endif /* CONFIG_ARMV6_M */
|
||||
|
@ -130,20 +129,20 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault)
|
|||
|
||||
_FaultThreadShow(esf);
|
||||
|
||||
if (_ScbMemFaultIsStacking()) {
|
||||
if (SCB->CFSR & CFSR_MSTKERR_Msk) {
|
||||
PR_EXC(" Stacking error\n");
|
||||
} else if (_ScbMemFaultIsUnstacking()) {
|
||||
} else if (SCB->CFSR & CFSR_MUNSTKERR_Msk) {
|
||||
PR_EXC(" Unstacking error\n");
|
||||
} else if (_ScbMemFaultIsDataAccessViolation()) {
|
||||
} else if (SCB->CFSR & CFSR_DACCVIOL_Msk) {
|
||||
PR_EXC(" Data Access Violation\n");
|
||||
if (_ScbMemFaultIsMmfarValid()) {
|
||||
PR_EXC(" Address: 0x%" PRIx32 "\n",
|
||||
_ScbMemFaultAddrGet());
|
||||
if (SCB->CFSR & CFSR_MMARVALID_Msk) {
|
||||
PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->MMFAR);
|
||||
if (fromHardFault) {
|
||||
_ScbMemFaultMmfarReset();
|
||||
/* clear MMAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
|
||||
}
|
||||
}
|
||||
} else if (_ScbMemFaultIsInstrAccessViolation()) {
|
||||
} else if (SCB->CFSR & CFSR_IACCVIOL_Msk) {
|
||||
PR_EXC(" Instruction Access Violation\n");
|
||||
}
|
||||
}
|
||||
|
@ -162,26 +161,26 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault)
|
|||
|
||||
_FaultThreadShow(esf);
|
||||
|
||||
if (_ScbBusFaultIsStacking()) {
|
||||
if (SCB->CFSR & CFSR_STKERR_Msk) {
|
||||
PR_EXC(" Stacking error\n");
|
||||
} else if (_ScbBusFaultIsUnstacking()) {
|
||||
} else if (SCB->CFSR & CFSR_UNSTKERR_Msk) {
|
||||
PR_EXC(" Unstacking error\n");
|
||||
} else if (_ScbBusFaultIsPrecise()) {
|
||||
} else if (SCB->CFSR & CFSR_PRECISERR_Msk) {
|
||||
PR_EXC(" Precise data bus error\n");
|
||||
if (_ScbBusFaultIsBfarValid()) {
|
||||
PR_EXC(" Address: 0x%" PRIx32 "\n",
|
||||
_ScbBusFaultAddrGet());
|
||||
if (SCB->CFSR & CFSR_BFARVALID_Msk) {
|
||||
PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->BFAR);
|
||||
if (fromHardFault) {
|
||||
_ScbBusFaultBfarReset();
|
||||
/* clear CFSR_BFAR[VALID] to reset */
|
||||
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
|
||||
}
|
||||
}
|
||||
/* it's possible to have both a precise and imprecise fault */
|
||||
if (_ScbBusFaultIsImprecise()) {
|
||||
if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
|
||||
PR_EXC(" Imprecise data bus error\n");
|
||||
}
|
||||
} else if (_ScbBusFaultIsImprecise()) {
|
||||
} else if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
|
||||
PR_EXC(" Imprecise data bus error\n");
|
||||
} else if (_ScbBusFaultIsInstrBusErr()) {
|
||||
} else if (SCB->CFSR & CFSR_IBUSERR_Msk) {
|
||||
PR_EXC(" Instruction bus error\n");
|
||||
}
|
||||
}
|
||||
|
@ -201,26 +200,27 @@ static void _UsageFault(const NANO_ESF *esf)
|
|||
_FaultThreadShow(esf);
|
||||
|
||||
/* bits are sticky: they stack and must be reset */
|
||||
if (_ScbUsageFaultIsDivByZero()) {
|
||||
if (SCB->CFSR & CFSR_DIVBYZERO_Msk) {
|
||||
PR_EXC(" Division by zero\n");
|
||||
}
|
||||
if (_ScbUsageFaultIsUnaligned()) {
|
||||
if (SCB->CFSR & CFSR_UNALIGNED_Msk) {
|
||||
PR_EXC(" Unaligned memory access\n");
|
||||
}
|
||||
if (_ScbUsageFaultIsNoCp()) {
|
||||
if (SCB->CFSR & CFSR_NOCP_Msk) {
|
||||
PR_EXC(" No coprocessor instructions\n");
|
||||
}
|
||||
if (_ScbUsageFaultIsInvalidPcLoad()) {
|
||||
if (SCB->CFSR & CFSR_INVPC_Msk) {
|
||||
PR_EXC(" Illegal load of EXC_RETURN into PC\n");
|
||||
}
|
||||
if (_ScbUsageFaultIsInvalidState()) {
|
||||
if (SCB->CFSR & CFSR_INVSTATE_Msk) {
|
||||
PR_EXC(" Illegal use of the EPSR\n");
|
||||
}
|
||||
if (_ScbUsageFaultIsUndefinedInstr()) {
|
||||
if (SCB->CFSR & CFSR_UNDEFINSTR_Msk) {
|
||||
PR_EXC(" Attempt to execute undefined instruction\n");
|
||||
}
|
||||
|
||||
_ScbUsageFaultAllFaultsReset();
|
||||
/* clear USFR sticky bits */
|
||||
SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,15 +257,15 @@ static void _HardFault(const NANO_ESF *esf)
|
|||
#if defined(CONFIG_ARMV6_M)
|
||||
_FaultThreadShow(esf);
|
||||
#elif defined(CONFIG_ARMV7_M)
|
||||
if (_ScbHardFaultIsBusErrOnVectorRead()) {
|
||||
if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) {
|
||||
PR_EXC(" Bus fault on vector table read\n");
|
||||
} else if (_ScbHardFaultIsForced()) {
|
||||
} else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) {
|
||||
PR_EXC(" Fault escalation (see below)\n");
|
||||
if (_ScbIsMemFault()) {
|
||||
if (SCB_MMFSR) {
|
||||
_MpuFault(esf, 1);
|
||||
} else if (_ScbIsBusFault()) {
|
||||
} else if (SCB_BFSR) {
|
||||
_BusFault(esf, 1);
|
||||
} else if (_ScbIsUsageFault()) {
|
||||
} else if (SCB_UFSR) {
|
||||
_UsageFault(esf);
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ static void _FaultDump(const NANO_ESF *esf, int fault)
|
|||
*/
|
||||
void _Fault(const NANO_ESF *esf)
|
||||
{
|
||||
int fault = _ScbActiveVectorGet();
|
||||
int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk;
|
||||
|
||||
FAULT_DUMP(esf, fault);
|
||||
|
||||
|
@ -379,7 +379,7 @@ void _FaultInit(void)
|
|||
{
|
||||
#if defined(CONFIG_ARMV6_M)
|
||||
#elif defined(CONFIG_ARMV7_M)
|
||||
_ScbDivByZeroFaultEnable();
|
||||
SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
|
||||
#else
|
||||
#error Unknown ARM architecture
|
||||
#endif /* CONFIG_ARMV6_M */
|
||||
|
|
|
@ -88,7 +88,7 @@ _stack_frame_endif:
|
|||
eors.n r0, r0
|
||||
msr BASEPRI, r0
|
||||
|
||||
/* this reimplements _ScbIsNestedExc() */
|
||||
/* this checks to see if we are in a nested exception */
|
||||
ldr ip, =_SCS_ICSR
|
||||
ldr ip, [ip]
|
||||
ands.w ip, #_SCS_ICSR_RETTOBASE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue