SAMA5D4: Add support for secure/FIQ interrupts; SAIC supports need to be be enabled unconditionally
This commit is contained in:
parent
9542994616
commit
3f6b1642ca
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* arch/arm/include/armv7-a/irq.h
|
* arch/arm/include/armv7-a/irq.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -277,6 +277,9 @@ static inline irqstate_t irqsave(void)
|
|||||||
(
|
(
|
||||||
"\tmrs %0, cpsr\n"
|
"\tmrs %0, cpsr\n"
|
||||||
"\tcpsid i\n"
|
"\tcpsid i\n"
|
||||||
|
#if defined(CONFIG_ARMV7A_DECODEFIQ)
|
||||||
|
"\tcpsid f\n"
|
||||||
|
#endif
|
||||||
: "=r" (cpsr)
|
: "=r" (cpsr)
|
||||||
:
|
:
|
||||||
: "memory"
|
: "memory"
|
||||||
@ -295,6 +298,9 @@ static inline irqstate_t irqenable(void)
|
|||||||
(
|
(
|
||||||
"\tmrs %0, cpsr\n"
|
"\tmrs %0, cpsr\n"
|
||||||
"\tcpsie i\n"
|
"\tcpsie i\n"
|
||||||
|
#if defined(CONFIG_ARMV7A_DECODEFIQ)
|
||||||
|
"\tcpsie f\n"
|
||||||
|
#endif
|
||||||
: "=r" (cpsr)
|
: "=r" (cpsr)
|
||||||
:
|
:
|
||||||
: "memory"
|
: "memory"
|
||||||
|
@ -73,7 +73,8 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define EXTERN extern "C"
|
#define EXTERN extern "C"
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#else
|
#else
|
||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,6 +63,11 @@ g_undeftmp:
|
|||||||
g_aborttmp:
|
g_aborttmp:
|
||||||
.word 0 /* Saved lr */
|
.word 0 /* Saved lr */
|
||||||
.word 0 /* Saved spsr */
|
.word 0 /* Saved spsr */
|
||||||
|
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||||
|
g_fiqtmp:
|
||||||
|
.word 0 /* Saved lr */
|
||||||
|
.word 0 /* Saved spsr */
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Assembly Macros
|
* Assembly Macros
|
||||||
@ -86,6 +91,7 @@ g_aborttmp:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
.globl arm_decodeirq
|
||||||
.globl arm_vectorirq
|
.globl arm_vectorirq
|
||||||
.type arm_vectorirq, %function
|
.type arm_vectorirq, %function
|
||||||
|
|
||||||
@ -153,7 +159,6 @@ arm_vectorirq:
|
|||||||
|
|
||||||
/* Restore the CPSR, SVC mode registers and return */
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
.Lnoirqset:
|
|
||||||
ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
msr spsr, r1
|
msr spsr, r1
|
||||||
ldmia r0, {r0-r15}^ /* Return */
|
ldmia r0, {r0-r15}^ /* Return */
|
||||||
@ -175,6 +180,7 @@ arm_vectorirq:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
.globl arm_syscall
|
||||||
.globl arm_vectorsvc
|
.globl arm_vectorsvc
|
||||||
.type arm_vectorsvc, %function
|
.type arm_vectorsvc, %function
|
||||||
|
|
||||||
@ -235,6 +241,7 @@ arm_vectorsvc:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
.globl arm_dataabort
|
||||||
.globl arm_vectordata
|
.globl arm_vectordata
|
||||||
.type arm_vectordata, %function
|
.type arm_vectordata, %function
|
||||||
|
|
||||||
@ -317,6 +324,7 @@ arm_vectordata:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
.globl arm_prefetchabort
|
||||||
.globl arm_vectorprefetch
|
.globl arm_vectorprefetch
|
||||||
.type arm_vectorprefetch, %function
|
.type arm_vectorprefetch, %function
|
||||||
|
|
||||||
@ -397,6 +405,7 @@ arm_vectorprefetch:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
.globl arm_undefinedinsn
|
||||||
.globl arm_vectorundefinsn
|
.globl arm_vectorundefinsn
|
||||||
.type arm_vectorundefinsn, %function
|
.type arm_vectorundefinsn, %function
|
||||||
|
|
||||||
@ -474,12 +483,86 @@ arm_vectorundefinsn:
|
|||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||||
|
.globl arm_decodefiq
|
||||||
|
#endif
|
||||||
.globl arm_vectorfiq
|
.globl arm_vectorfiq
|
||||||
.type arm_vectorfiq, %function
|
.type arm_vectorfiq, %function
|
||||||
|
|
||||||
arm_vectorfiq:
|
arm_vectorfiq:
|
||||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||||
# error Missing logic
|
/* On entry we are free to use the FIQ mode registers r8 through r14 */
|
||||||
|
|
||||||
|
ldr r13, .Lfiqtmp /* Points to temp storage */
|
||||||
|
sub lr, lr, #4 /* Fixup return */
|
||||||
|
str lr, [r13] /* Save in temp storage */
|
||||||
|
mrs lr, spsr /* Get SPSR_fiq */
|
||||||
|
str lr, [r13, #4] /* Save in temp storage */
|
||||||
|
|
||||||
|
/* Then switch back to SVC mode */
|
||||||
|
|
||||||
|
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||||
|
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||||
|
msr cpsr_c, lr /* Switch to SVC mode */
|
||||||
|
|
||||||
|
/* Create a context structure. First set aside a stack frame
|
||||||
|
* and store r0-r12 into the frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||||
|
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||||
|
|
||||||
|
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||||
|
|
||||||
|
add r1, sp, #XCPTCONTEXT_SIZE
|
||||||
|
mov r2, r14
|
||||||
|
|
||||||
|
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||||
|
|
||||||
|
ldr r0, .Lfiqtmp /* Points to temp storage */
|
||||||
|
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||||
|
|
||||||
|
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||||
|
stmia r0, {r1-r4}
|
||||||
|
|
||||||
|
/* Then call the IRQ handler with interrupts disabled. */
|
||||||
|
|
||||||
|
mov fp, #0 /* Init frame pointer */
|
||||||
|
mov r0, sp /* Get r0=xcp */
|
||||||
|
|
||||||
|
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
|
ldr sp, .Lfiqstackbase /* SP = interrupt stack base */
|
||||||
|
str r0, [sp] /* Save the user stack pointer */
|
||||||
|
mov r4, sp /* Save the SP in a preserved register */
|
||||||
|
bic sp, sp, #7 /* Force 8-byte alignement */
|
||||||
|
bl arm_decodefiq /* Call the handler */
|
||||||
|
ldr sp, [r4] /* Restore the user stack pointer */
|
||||||
|
#else
|
||||||
|
mov r4, sp /* Save the SP in a preserved register */
|
||||||
|
bic sp, sp, #7 /* Force 8-byte alignement */
|
||||||
|
bl arm_decodefiq /* Call the handler */
|
||||||
|
mov sp, r4 /* Restore the possibly unaligned stack pointer */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Upon return from arm_decodefiq, r0 holds the pointer to the register
|
||||||
|
* state save area to use to restore the registers. This may or may not
|
||||||
|
* be the same value that was passed to arm_decodefiq: It will differ if a
|
||||||
|
* context switch is required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Restore the CPSR, SVC mode registers and return */
|
||||||
|
|
||||||
|
ldr r1, [r0, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||||
|
msr spsr, r1
|
||||||
|
ldmia r0, {r0-r15}^ /* Return */
|
||||||
|
|
||||||
|
.Lfiqtmp:
|
||||||
|
.word g_fiqtmp
|
||||||
|
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
|
.Lfiqstackbase:
|
||||||
|
.word g_fiqstackbase
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
subs pc, lr, #4
|
subs pc, lr, #4
|
||||||
#endif
|
#endif
|
||||||
@ -492,15 +575,33 @@ arm_vectorfiq:
|
|||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
.bss
|
.bss
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
.globl g_intstackalloc
|
.globl g_intstackalloc
|
||||||
.type g_intstackalloc, object
|
.type g_intstackalloc, object
|
||||||
.globl g_intstackbase
|
.globl g_intstackbase
|
||||||
.type g_intstackbase, object
|
.type g_intstackbase, object
|
||||||
|
|
||||||
g_intstackalloc:
|
g_intstackalloc:
|
||||||
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||||
g_intstackbase:
|
g_intstackbase:
|
||||||
.skip 4
|
.skip 4
|
||||||
.size g_intstackbase, 4
|
.size g_intstackbase, 4
|
||||||
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
.size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||||
#endif
|
|
||||||
|
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||||
|
|
||||||
|
.globl g_fiqstackalloc
|
||||||
|
.type g_fiqstackalloc, object
|
||||||
|
.globl g_fiqstackbase
|
||||||
|
.type g_fiqstackbase, object
|
||||||
|
|
||||||
|
g_fiqstackalloc:
|
||||||
|
.skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
|
||||||
|
g_fiqstackbase:
|
||||||
|
.skip 4
|
||||||
|
.size g_fiqstackbase, 4
|
||||||
|
.size g_fiqstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||||
|
|
||||||
|
#endif /* CONFIG_ARMV7A_DECODEFIQ */
|
||||||
|
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */
|
||||||
.end
|
.end
|
||||||
|
@ -80,6 +80,7 @@ config SAMA5_HAVE_HSMCI2
|
|||||||
config SAMA5_HAVE_SAIC
|
config SAMA5_HAVE_SAIC
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
select ARMV7A_DECODEFIQ
|
||||||
|
|
||||||
config SAMA5_HAVE_SBM
|
config SAMA5_HAVE_SBM
|
||||||
bool
|
bool
|
||||||
@ -531,7 +532,8 @@ config SAMA5_SECURE
|
|||||||
bool "Enable secure features"
|
bool "Enable secure features"
|
||||||
default n
|
default n
|
||||||
depends on SAMA5_HAVE_TRUSTZONE && EXPERIMENTAL
|
depends on SAMA5_HAVE_TRUSTZONE && EXPERIMENTAL
|
||||||
select ARMV7A_DECODEFIQ if SAMA5_HAVE_SAIC
|
---help---
|
||||||
|
Does not do anything now, but may in the future
|
||||||
|
|
||||||
config SAMA5_PIO_IRQ
|
config SAMA5_PIO_IRQ
|
||||||
bool "PIO pin interrupts"
|
bool "PIO pin interrupts"
|
||||||
|
@ -136,7 +136,7 @@ static void sam_dumpaic(const char *msg, uintptr_t base, int irq)
|
|||||||
|
|
||||||
/* SAMA5D4 does not have the FFSR register */
|
/* SAMA5D4 does not have the FFSR register */
|
||||||
|
|
||||||
#ifdef SAM_AIC_FFSR
|
#if defined(SAM_AIC_FFSR)
|
||||||
lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n",
|
lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n",
|
||||||
getreg32(base + SAM_AIC_IMR_OFFSET),
|
getreg32(base + SAM_AIC_IMR_OFFSET),
|
||||||
getreg32(base + SAM_AIC_CISR_OFFSET),
|
getreg32(base + SAM_AIC_CISR_OFFSET),
|
||||||
@ -253,7 +253,7 @@ static uint32_t *sam_fiqhandler(int irq, uint32_t *regs)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
static inline bool sam_aic_ish64mx(uint32_t irq)
|
static inline bool sam_aic_ish64mx(uint32_t irq)
|
||||||
{
|
{
|
||||||
return (irq == SAM_IRQ_ARM ||
|
return (irq == SAM_IRQ_ARM ||
|
||||||
@ -280,7 +280,7 @@ static inline bool sam_aic_ish64mx(uint32_t irq)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
static bool sam_aic_issecure(uint32_t irq)
|
static bool sam_aic_issecure(uint32_t irq)
|
||||||
{
|
{
|
||||||
uintptr_t regaddr;
|
uintptr_t regaddr;
|
||||||
@ -418,7 +418,7 @@ void up_irqinitialize(void)
|
|||||||
|
|
||||||
sam_aic_initialize(SAM_AIC_VBASE);
|
sam_aic_initialize(SAM_AIC_VBASE);
|
||||||
|
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
/* Initialize the Secure Advanced Interrupt Controller (SAIC) */
|
/* Initialize the Secure Advanced Interrupt Controller (SAIC) */
|
||||||
|
|
||||||
sam_aic_initialize(SAM_SAIC_VBASE);
|
sam_aic_initialize(SAM_SAIC_VBASE);
|
||||||
@ -621,10 +621,10 @@ uint32_t *arm_decodeirq(uint32_t *regs)
|
|||||||
return sam_decodeirq(SAM_AIC_VBASE, regs);
|
return sam_decodeirq(SAM_AIC_VBASE, regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
/* This is the entry point from the ARM FIQ vector handler */
|
/* This is the entry point from the ARM FIQ vector handler */
|
||||||
|
|
||||||
uint32_t *arm_decodefiq(uint32_t *regs)
|
uint32_t *arm_decodefiq(FAR uint32_t *regs)
|
||||||
{
|
{
|
||||||
/* In order to distinguish a FIQ from a true secure interrupt we need to
|
/* In order to distinguish a FIQ from a true secure interrupt we need to
|
||||||
* check the state of the FIQ line in the SAIC_CISR register.
|
* check the state of the FIQ line in the SAIC_CISR register.
|
||||||
@ -632,7 +632,7 @@ uint32_t *arm_decodefiq(uint32_t *regs)
|
|||||||
|
|
||||||
if ((getreg32(SAM_SAIC_CISR) & AIC_CISR_NFIQ) != 0)
|
if ((getreg32(SAM_SAIC_CISR) & AIC_CISR_NFIQ) != 0)
|
||||||
{
|
{
|
||||||
return sam_fiqhandler(SAM_IRQ_FIQ, regs);
|
return arm_doirq(SAM_IRQ_FIQ, regs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -681,7 +681,7 @@ static void sam_disable_irq(uintptr_t base, int irq)
|
|||||||
|
|
||||||
void up_disable_irq(int irq)
|
void up_disable_irq(int irq)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
if (sam_aic_issecure(irq))
|
if (sam_aic_issecure(irq))
|
||||||
{
|
{
|
||||||
sam_disable_irq(SAM_SAIC_VBASE, irq);
|
sam_disable_irq(SAM_SAIC_VBASE, irq);
|
||||||
@ -733,7 +733,7 @@ static void sam_enable_irq(uintptr_t base, int irq)
|
|||||||
|
|
||||||
void up_enable_irq(int irq)
|
void up_enable_irq(int irq)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
if (sam_aic_issecure(irq))
|
if (sam_aic_issecure(irq))
|
||||||
{
|
{
|
||||||
sam_enable_irq(SAM_SAIC_VBASE, irq);
|
sam_enable_irq(SAM_SAIC_VBASE, irq);
|
||||||
@ -809,7 +809,7 @@ static int sam_prioritize_irq(uint32_t base, int irq, int priority)
|
|||||||
|
|
||||||
int up_prioritize_irq(int irq, int priority)
|
int up_prioritize_irq(int irq, int priority)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
if (sam_aic_issecure(irq))
|
if (sam_aic_issecure(irq))
|
||||||
{
|
{
|
||||||
sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority);
|
sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority);
|
||||||
@ -867,7 +867,7 @@ static void _sam_irq_srctype(uintptr_t base, int irq,
|
|||||||
|
|
||||||
void sam_irq_srctype(int irq, enum sam_srctype_e srctype)
|
void sam_irq_srctype(int irq, enum sam_srctype_e srctype)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC)
|
#if defined(CONFIG_SAMA5_HAVE_SAIC)
|
||||||
if (sam_aic_issecure(irq))
|
if (sam_aic_issecure(irq))
|
||||||
{
|
{
|
||||||
_sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype);
|
_sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype);
|
||||||
|
@ -118,7 +118,7 @@ CONFIG_ARMV7A_TOOLCHAIN_CODESOURCERYW=y
|
|||||||
# CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIL is not set
|
# CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIL is not set
|
||||||
# CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIW is not set
|
# CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIW is not set
|
||||||
# CONFIG_ARMV7A_TOOLCHAIN_GNU_OABI is not set
|
# CONFIG_ARMV7A_TOOLCHAIN_GNU_OABI is not set
|
||||||
# CONFIG_ARMV7A_DECODEFIQ is not set
|
CONFIG_ARMV7A_DECODEFIQ=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# SAMA5 Configuration Options
|
# SAMA5 Configuration Options
|
||||||
@ -213,7 +213,6 @@ CONFIG_SAMA5_USART3=y
|
|||||||
# CONFIG_SAMA5_FUSE is not set
|
# CONFIG_SAMA5_FUSE is not set
|
||||||
CONFIG_SAMA5_MPDDRC=y
|
CONFIG_SAMA5_MPDDRC=y
|
||||||
# CONFIG_SAMA5_VDEC is not set
|
# CONFIG_SAMA5_VDEC is not set
|
||||||
# CONFIG_SAMA5_SECURE is not set
|
|
||||||
# CONFIG_SAMA5_PIO_IRQ is not set
|
# CONFIG_SAMA5_PIO_IRQ is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user