diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index c98379d9272..60ccda2f354 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -80,7 +80,6 @@ config SAMA5_HAVE_HSMCI2 config SAMA5_HAVE_SAIC bool default n - select ARMV7A_DECODEFIQ config SAMA5_HAVE_SBM bool @@ -276,6 +275,12 @@ config SAMA5_SMD bool "SMD Soft Modem (SMD)" default n +config SAMA5_SAIC + bool "Secure Advanced Interrupt Controller (SAIC)" + default n + depends on SAMA5_HAVE_SAIC + select ARMV7A_DECODEFIQ + config SAMA5_UART0 bool "UART 0" default y diff --git a/arch/arm/src/sama5/chip/sam_sfr.h b/arch/arm/src/sama5/chip/sam_sfr.h index 7375a434b1e..a050f9a01b2 100644 --- a/arch/arm/src/sama5/chip/sam_sfr.h +++ b/arch/arm/src/sama5/chip/sam_sfr.h @@ -69,6 +69,7 @@ #ifdef ATSAMA5D4 # define SAM_SFR_SN0_OFFSET 0x004c /* Serial Number 0 Register */ # define SAM_SFR_SN1_OFFSET 0x0050 /* Serial Number 1 Register */ +# define SAM_SFR_AICREDIR_OFFSET 0x0054 /* AIC Redirection Register */ #endif /* SFR Register Addresses ***********************************************************/ @@ -88,8 +89,9 @@ #define SAM_SFR_EBICFG (SAM_SFR_VBASE+SAM_SFR_EBICFG_OFFSET) #ifdef ATSAMA5D4 -# define SAM_SFR_SN0 (SAM_SFR_VBASE+SAM_SFR_SN0_OFFSET) -# define SAM_SFR_SN1 (SAM_SFR_VBASE+SAM_SFR_SN1_OFFSET) +# define SAM_SFR_SN0 (SAM_SFR_VBASE+SAM_SFR_SN0_OFFSET) +# define SAM_SFR_SN1 (SAM_SFR_VBASE+SAM_SFR_SN1_OFFSET) +# define SAM_SFR_AICREDIR (SAM_SFR_VBASE+SAM_SFR_AICREDIR_OFFSET) #endif /* SFR Register Bit Definitions *****************************************************/ @@ -215,6 +217,13 @@ #ifdef ATSAMA5D4 /* Serial Number 0 Register (32-bit value) */ /* Serial Number 1 Register (32-bit value) */ + +/* AIC Redirection Register */ + +# define SFR_AICREDIR_ENABLE (1 << 0) /* Bit 0: 1=All interrupts to AIC */ +# define SFR_AICREDIR_DISABLE (0) /* Bit 0: 0=Secure interrupts to SAIC */ +# define SFR_AICREDIR_KEY (0x5f67b102) /* Bits 1-31: Access key */ + #endif #endif /* __ARCH_ARM_SRC_SAMA5_CHIP_SAM_SFR_H */ diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c index 5a852fd89e7..dc7dfce5634 100644 --- a/arch/arm/src/sama5/sam_irq.c +++ b/arch/arm/src/sama5/sam_irq.c @@ -61,6 +61,7 @@ #include "chip/sam_aic.h" #include "chip/sam_matrix.h" #include "chip/sam_aximx.h" +#include "chip/sam_sfr.h" #include "sam_irq.h" @@ -100,7 +101,7 @@ static const uint8_t g_srctype[SCRTYPE_NTYPES] = * peripheral interrupts are secured or not. */ -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) static const uint32_t g_h64mxpids[3] = { H64MX_SPSELR0_PIDS, H64MX_SPSELR1_PIDS, H64MX_SPSELR2_PIDS @@ -260,7 +261,7 @@ static uint32_t *sam_fiqhandler(int irq, uint32_t *regs) * ****************************************************************************/ -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) static bool sam_aic_issecure(uint32_t irq) { uintptr_t regaddr; @@ -294,6 +295,46 @@ static bool sam_aic_issecure(uint32_t irq) } #endif +/**************************************************************************** + * Name: sam_aic_redirection + * + * Description: + * Redirect all interrupts to the AIC. This function is only compiled if + * (1) the architecture supports an SAIC (CONFIG_SAMA5_HAVE_SAIC), but (2) + * Use of the SAIC has not been selected (!CONFIG_SAMA5_SAIC). + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_HAVE_SAIC) && !defined(CONFIG_SAMA5_SAIC) +static void sam_aic_redirection(void) +{ + unsigned int regval; + + /* Check if interrupts are already redirected to the AIC */ + + regval = getreg32(SAM_SFR_AICREDIR); + if ((regval & SFR_AICREDIR_ENABLE) == 0) + { + /* Enable redirection of all interrupts to the AIC */ + + regval = getreg32(SAM_SFR_SN1); + regval ^= SFR_AICREDIR_KEY; + regval |= SFR_AICREDIR_ENABLE; + putreg32(regval, SAM_SFR_AICREDIR); + +#if defined(CONFIG_DEBUG_IRQ) + /* Check if redirection was successfully enabled */ + + regval = getreg32(SAM_SFR_AICREDIR); + lldbg("Interrupts %s redirected to the AIC\n", + (regval & SFR_AICREDIR_ENABLE) != 0 ? "ARE" : "NOT"); +#endif + } +} +#else +# define sam_aic_redirection() +#endif + /**************************************************************************** * Name: sam_aic_initialize * @@ -395,11 +436,15 @@ void up_irqinitialize(void) } #endif + /* Redirect all interrupts to the AIC if so configured */ + + sam_aic_redirection(); + /* Initialize the Advanced Interrupt Controller (AIC) */ sam_aic_initialize(SAM_AIC_VBASE); -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) /* Initialize the Secure Advanced Interrupt Controller (SAIC) */ sam_aic_initialize(SAM_SAIC_VBASE); @@ -602,7 +647,7 @@ uint32_t *arm_decodeirq(uint32_t *regs) return sam_decodeirq(SAM_AIC_VBASE, regs); } -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) /* This is the entry point from the ARM FIQ vector handler */ uint32_t *arm_decodefiq(FAR uint32_t *regs) @@ -674,7 +719,7 @@ static void sam_disable_irq(uintptr_t base, int irq) void up_disable_irq(int irq) { -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) if (sam_aic_issecure(irq)) { sam_disable_irq(SAM_SAIC_VBASE, irq); @@ -726,7 +771,7 @@ static void sam_enable_irq(uintptr_t base, int irq) void up_enable_irq(int irq) { -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) if (sam_aic_issecure(irq)) { sam_enable_irq(SAM_SAIC_VBASE, irq); @@ -802,7 +847,7 @@ static int sam_prioritize_irq(uint32_t base, int irq, int priority) int up_prioritize_irq(int irq, int priority) { -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) if (sam_aic_issecure(irq)) { sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority); @@ -860,7 +905,7 @@ static void _sam_irq_srctype(uintptr_t base, int irq, void sam_irq_srctype(int irq, enum sam_srctype_e srctype) { -#if defined(CONFIG_SAMA5_HAVE_SAIC) +#if defined(CONFIG_SAMA5_SAIC) if (sam_aic_issecure(irq)) { _sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype);