From fb25ba907c387f288c0a0102007cca786582abc3 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 20 Jun 2014 15:22:00 -0600 Subject: [PATCH] SAMA5D4: Add partial support for secure interrupt controller (SAIC) --- arch/arm/src/armv7-a/Kconfig | 11 +- arch/arm/src/armv7-a/arm_vectors.S | 9 +- arch/arm/src/sama5/Kconfig | 11 + arch/arm/src/sama5/chip/sam_aic.h | 2 +- arch/arm/src/sama5/chip/sam_matrix.h | 8 +- arch/arm/src/sama5/sam_irq.c | 383 ++++++++++++++++++++------- configs/sama5d4-ek/ramtest/defconfig | 3 + 7 files changed, 321 insertions(+), 106 deletions(-) diff --git a/arch/arm/src/armv7-a/Kconfig b/arch/arm/src/armv7-a/Kconfig index 5636a15338..ba56052f4b 100644 --- a/arch/arm/src/armv7-a/Kconfig +++ b/arch/arm/src/armv7-a/Kconfig @@ -55,4 +55,13 @@ config ARMV7A_OABI_TOOLCHAIN default n depends on ARMV7A_TOOLCHAIN_BUILDROOT ---help--- - Most of the older buildroot toolchains are OABI and are named arm-nuttx-elf- vs. arm-nuttx-eabi- + Most of the older buildroot toolchains are OABI and are named + arm-nuttx-elf- vs. arm-nuttx-eabi- + +config ARMV7A_DECODEFIQ + bool "FIQ Handler" + default n + ---help--- + Select this option if your platform supports the function + arm_decodefiq(). This is used primarily to support secure TrustZone + interrupts received on the FIQ vector. diff --git a/arch/arm/src/armv7-a/arm_vectors.S b/arch/arm/src/armv7-a/arm_vectors.S index ecd21b9cca..c3ea3063fe 100644 --- a/arch/arm/src/armv7-a/arm_vectors.S +++ b/arch/arm/src/armv7-a/arm_vectors.S @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/armv7-a/arm_vectors.S * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -469,7 +469,8 @@ arm_vectorundefinsn: * Name: arm_vectorfiq * * Description: - * Shouldn't happen + * Shouldn't happen unless a arm_decodefiq() is provided. FIQ is primarily used + * with the TrustZone feature in order to handler secure interrupts. * ************************************************************************************/ @@ -477,7 +478,11 @@ arm_vectorundefinsn: .type arm_vectorfiq, %function arm_vectorfiq: +#ifdef CONFIG_ARMV7A_DECODEFIQ +# error Missing logic +#else subs pc, lr, #4 +#endif .size arm_vectorfiq, . - arm_vectorfiq /************************************************************************************ diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index c4a04e9932..c1e8d10e55 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -101,6 +101,10 @@ config SAMA5_HAVE_TC2 bool default n +config SAMA5_HAVE_TRUSTZONE + bool + default n + config SAMA5_HAVE_TWI3 bool default n @@ -135,6 +139,7 @@ config ARCH_CHIP_SAMA5D4 select SAMA5_HAVE_SPI2 select SAMA5_HAVE_TC1 select SAMA5_HAVE_TC2 + select SAMA5_HAVE_TRUSTZONE select SAMA5_HAVE_TWI3 select ARCH_NAND_HWECC @@ -522,6 +527,12 @@ config SAMA5_VDEC endmenu # SAMA5 Peripheral Support +config SAMA5_SECURE + bool "Enable secure features" + default n + depends on SAMA5_HAVE_TRUSTZONE && EXPERIMENTAL + select ARMV7A_DECODEFIQ if SAMA5_HAVE_SAIC + config SAMA5_PIO_IRQ bool "PIO pin interrupts" ---help--- diff --git a/arch/arm/src/sama5/chip/sam_aic.h b/arch/arm/src/sama5/chip/sam_aic.h index 4da2cabb18..8f909fd182 100644 --- a/arch/arm/src/sama5/chip/sam_aic.h +++ b/arch/arm/src/sama5/chip/sam_aic.h @@ -108,7 +108,7 @@ #define SAM_AIC_WPMR (SAM_AIC_VBASE+SAM_AIC_WPMR_OFFSET) #define SAM_AIC_WPSR (SAM_AIC_VBASE+SAM_AIC_WPSR_OFFSET) -#ifdef SAMA5_HAVE_SAIC +#ifdef CONFIG_SAMA5_HAVE_SAIC # define SAM_SAIC_SSR (SAM_SAIC_VBASE+SAM_AIC_SSR_OFFSET) # define SAM_SAIC_SMR (SAM_SAIC_VBASE+SAM_AIC_SMR_OFFSET) # define SAM_SAIC_SVR (SAM_SAIC_VBASE+SAM_AIC_SVR_OFFSET) diff --git a/arch/arm/src/sama5/chip/sam_matrix.h b/arch/arm/src/sama5/chip/sam_matrix.h index 751dcb5f57..d75118b8c2 100644 --- a/arch/arm/src/sama5/chip/sam_matrix.h +++ b/arch/arm/src/sama5/chip/sam_matrix.h @@ -203,6 +203,7 @@ # define SAM_MATRIX_SRTSR11_OFFSET 0x02ac /* Security Region Top Slave 11 Register */ # define SAM_MATRIX_SRTSR12_OFFSET 0x02b0 /* Security Region Top Slave 12 Register */ +# define SAM_MATRIX_SPSELR_OFFSET(n) (0x02c0 + ((n) << 2)) # define SAM_MATRIX_SPSELR1_OFFSET 0x02c0 /* Security Peripheral Select 1 Register */ # define SAM_MATRIX_SPSELR2_OFFSET 0x02c4 /* Security Peripheral Select 2 Register */ # define SAM_MATRIX_SPSELR3_OFFSET 0x02c8 /* Security Peripheral Select 3 Register */ @@ -290,10 +291,7 @@ #endif /* ATSAMA5D3 */ #ifdef ATSAMA5D4 -/* HMATRIX0 (H64MX) - * - * - */ +/* HMATRIX0 (H64MX) */ # define SAM_MATRIX0_MCFG(n)) (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG_OFFSET(n)) # define SAM_MATRIX0_MCFG0 (SAM_MATRIX64_VBASE+SAM_MATRIX_MCFG0_OFFSET) @@ -414,6 +412,7 @@ # define SAM_MATRIX0_SRTSR11 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR11_OFFSET) # define SAM_MATRIX0_SRTSR12 (SAM_MATRIX64_VBASE+SAM_MATRIX_SRTSR12_OFFSET) +# define SAM_MATRIX0_SPSELR(n) (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR_OFFSET(n)) # define SAM_MATRIX0_SPSELR1 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR1_OFFSET) # define SAM_MATRIX0_SPSELR2 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR2_OFFSET) # define SAM_MATRIX0_SPSELR3 (SAM_MATRIX64_VBASE+SAM_MATRIX_SPSELR3_OFFSET) @@ -539,6 +538,7 @@ # define SAM_MATRIX1_SRTSR11 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR11_OFFSET) # define SAM_MATRIX1_SRTSR12 (SAM_MATRIX32_VBASE+SAM_MATRIX_SRTSR12_OFFSET) +# define SAM_MATRIX1_SPSELR(n) (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR_OFFSET(n)) # define SAM_MATRIX1_SPSELR1 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR1_OFFSET) # define SAM_MATRIX1_SPSELR2 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR2_OFFSET) # define SAM_MATRIX1_SPSELR3 (SAM_MATRIX32_VBASE+SAM_MATRIX_SPSELR3_OFFSET) diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c index ca7d63987b..d8cfdfd8ab 100644 --- a/arch/arm/src/sama5/sam_irq.c +++ b/arch/arm/src/sama5/sam_irq.c @@ -107,47 +107,57 @@ static const uint8_t g_srctype[SCRTYPE_NTYPES] = ****************************************************************************/ #if defined(CONFIG_DEBUG_IRQ) -static void sam_dumpaic(const char *msg, int irq) +static void sam_dumpaic(const char *msg, uintptr_t base, int irq) { irqstate_t flags; flags = irqsave(); - lldbg("AIC (%s, irq=%d):\n", msg, irq); + lldbg("AIC (%s, base=%08x irq=%d):\n", msg, base, irq); /* Select the register set associated with this irq */ - putreg32(irq, SAM_AIC_SSR); + putreg32(irq, base + SAM_AIC_SSR_OFFSET); /* Then dump all of the (readable) register contents */ lldbg(" SSR: %08x SMR: %08x SVR: %08x IVR: %08x\n", - getreg32(SAM_AIC_SSR), getreg32(SAM_AIC_SMR), - getreg32(SAM_AIC_SVR), getreg32(SAM_AIC_IVR)); + getreg32(base + SAM_AIC_SSR_OFFSET), + getreg32(base + SAM_AIC_SMR_OFFSET), + getreg32(base + SAM_AIC_SVR_OFFSET), + getreg32(base + SAM_AIC_IVR_OFFSET)); lldbg(" FVR: %08x ISR: %08x\n", - getreg32(SAM_AIC_FVR), getreg32(SAM_AIC_ISR)); + getreg32(base + SAM_AIC_FVR_OFFSET), + getreg32(base + SAM_AIC_ISR_OFFSET)); lldbg(" IPR: %08x %08x %08x %08x\n", - getreg32(SAM_AIC_IPR0), getreg32(SAM_AIC_IPR1), - getreg32(SAM_AIC_IPR2), getreg32(SAM_AIC_IPR3)); + getreg32(base + SAM_AIC_IPR0_OFFSET), + getreg32(base + SAM_AIC_IPR1_OFFSET), + getreg32(base + SAM_AIC_IPR2_OFFSET), + getreg32(base + SAM_AIC_IPR3_OFFSET)); /* SAMA5D4 does not have the FFSR register */ #ifdef SAM_AIC_FFSR lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n", - getreg32(SAM_AIC_IMR), getreg32(SAM_AIC_CISR), - getreg32(SAM_AIC_SPU), getreg32(SAM_AIC_FFSR)); + getreg32(base + SAM_AIC_IMR_OFFSET), + getreg32(base + SAM_AIC_CISR_OFFSET), + getreg32(base + SAM_AIC_SPU_OFFSET), + getreg32(base + SAM_AIC_FFSR_OFFSET)); #else lldbg(" IMR: %08x CISR: %08x SPU: %08x\n", - getreg32(SAM_AIC_IMR), getreg32(SAM_AIC_CISR), - getreg32(SAM_AIC_SPU)); + getreg32(base + SAM_AIC_IMR_OFFSET), + getreg32(base + SAM_AIC_CISR_OFFSET), + getreg32(base + SAM_AIC_SPU_OFFSET)); #endif lldbg(" DCR: %08x WPMR: %08x WPSR: %08x\n", - getreg32(SAM_AIC_DCR), getreg32(SAM_AIC_WPMR), - getreg32(SAM_AIC_WPSR)); + getreg32(base + SAM_AIC_DCR_OFFSET), + getreg32(base + SAM_AIC_WPMR_OFFSET), + getreg32(base + SAM_AIC_WPSR_OFFSET)); + irqrestore(flags); } #else -# define sam_dumpaic(msg, irq) +# define sam_dumpaic(msg, base, irq) #endif /**************************************************************************** @@ -232,6 +242,143 @@ static uint32_t *sam_fiqhandler(int irq, uint32_t *regs) return regs; /* Won't get here */ } +/**************************************************************************** + * Name: sam_aic_ish64mx + * + * Description: + * Return true if the peripheral is H64 Matrix. + * + * Input Parameter: + * PID = IRQ number + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) +static inline bool sam_aic_ish64mx(uint32_t irq) +{ + return (irq == SAM_IRQ_ARM || + irq == SAM_IRQ_XDMAC0 || + /* irq == SAM_IRQ_CPKCC || */ + irq == SAM_IRQ_AESB || + irq == SAM_IRQ_MPDDRC || + irq == SAM_IRQ_VDEC || + irq == SAM_IRQ_XDMAC1 || + irq == SAM_IRQ_LCDC || + irq == SAM_IRQ_ISI || + irq == SAM_IRQ_L2CC); +} +#endif + +/**************************************************************************** + * Name: sam_aic_issecure + * + * Description: + * Return true if the peripheral secure. + * + * Input Parameter: + * PID = IRQ number + * + ****************************************************************************/ + +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) +static bool sam_aic_issecure(uint32_t irq) +{ + uintptr_t regaddr; + uint32_t bit; + int regndx; + + /* Get the register index and bit mask */ + + regndx = (irq >> 5); + bit = ((uint32_t)1 << (irq & 0x1f)); + + /* Get the SPSELR register address */ + + if (sam_aic_ish64mx(irq)) + { + /* H64MX. Use Matrix 0 */ + + regaddr = SAM_MATRIX0_SPSELR(regndx); + } + else + { + /* H32MX. Use Matrix 1 */ + + regaddr = SAM_MATRIX1_SPSELR(regndx); + } + + /* Return true if the bit corresponding to this IRQ is zero */ + + return (getreg32(regaddr) & bit) == 0; +} +#endif + +/**************************************************************************** + * Name: sam_aic_initialize + * + * Description: + * Initialize the AIC or the SAIC. + * + ****************************************************************************/ + +static void sam_aic_initialize(uintptr_t base) +{ + int i; + + /* Unprotect SMR, SVR, SPU and DCR register */ + + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); + + /* Configure the FIQ and the IRQs. */ + + for (i = 0; i < SAM_IRQ_NINT; i++) + { + /* Select the interrupt registers */ + + putreg32(i, base + SAM_AIC_SSR_OFFSET); + + /* Disable the interrupt */ + + putreg32(AIC_IDCR_INTD, base + SAM_AIC_IDCR_OFFSET); + + /* Set the (unused) FIQ/IRQ handler */ + + if (i == SAM_PID_FIQ) + { + putreg32((uint32_t)sam_fiqhandler, base + SAM_AIC_SVR_OFFSET); + } + else + { + putreg32((uint32_t)arm_doirq, base + SAM_AIC_SVR_OFFSET); + } + + /* Set the default interrupt priority */ + + putreg32(SAM_DEFAULT_PRIOR, base + SAM_AIC_SMR_OFFSET); + + /* Clear any pending interrupt */ + + putreg32(AIC_ICCR_INTCLR, base + SAM_AIC_ICCR_OFFSET); + } + + /* Set the (unused) spurious interrupt handler */ + + putreg32((uint32_t)sam_spurious, base + SAM_AIC_SPU_OFFSET); + + /* Perform 8 interrupt acknowledgements by writing any value to the + * EOICR register. + */ + + for (i = 0; i < 8 ; i++) + { + putreg32(AIC_EOICR_ENDIT, base + SAM_AIC_EOICR_OFFSET); + } + + /* Restore protection and the interrupt state */ + + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -251,7 +398,6 @@ void up_irqinitialize(void) #if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) size_t vectorsize; #endif - int i; /* The following operations need to be atomic, but since this function is * called early in the initialization sequence, we expect to have exclusive @@ -268,58 +414,16 @@ void up_irqinitialize(void) } #endif - /* Unprotect SMR, SVR, SPU and DCR register */ + /* Initialize the Advanced Interrupt Controller (AIC) */ - putreg32(AIC_WPMR_WPKEY, SAM_AIC_WPMR); + sam_aic_initialize(SAM_AIC_VBASE); - /* Configure the FIQ and the IRQs. */ +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) + /* Initialize the Secure Advanced Interrupt Controller (SAIC) */ - for (i = 0; i < SAM_IRQ_NINT; i++) - { - /* Select the interrupt registers */ + sam_aic_initialize(SAM_SAIC_VBASE); - putreg32(i, SAM_AIC_SSR); - - /* Disable the interrupt */ - - putreg32(AIC_IDCR_INTD, SAM_AIC_IDCR); - - /* Set the (unused) FIQ/IRQ handler */ - - if (i == SAM_PID_FIQ) - { - putreg32((uint32_t)sam_fiqhandler, SAM_AIC_SVR); - } - else - { - putreg32((uint32_t)arm_doirq, SAM_AIC_SVR); - } - - /* Set the default interrupt priority */ - - putreg32(SAM_DEFAULT_PRIOR, SAM_AIC_SMR); - - /* Clear any pending interrupt */ - - putreg32(AIC_ICCR_INTCLR, SAM_AIC_ICCR); - } - - /* Set the (unused) spurious interrupt handler */ - - putreg32((uint32_t)sam_spurious, SAM_AIC_SPU); - - /* Perform 8 interrupt acknowledgements by writing any value to the - * EOICR register. - */ - - for (i = 0; i < 8 ; i++) - { - putreg32(AIC_EOICR_ENDIT, SAM_AIC_EOICR); - } - - /* Restore protection and the interrupt state */ - - putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR); +#endif #if defined(CONFIG_ARCH_LOWVECTORS) /* If CONFIG_ARCH_LOWVECTORS is defined, then the vectors located at the @@ -337,7 +441,7 @@ void up_irqinitialize(void) * 0x0000:00000. VBAR == 0x0000:0000. * * This method is used when booting from ISRAM or NOR FLASH. In - & that case, vectors must lie at the beginning of NOFR FLASH. + * that case, vectors must lie at the beginning of NOFR FLASH. * * 3. Set the Cortex-A5 VBAR register so that the vector table address * is moved to a location other than 0x0000:0000. @@ -440,7 +544,7 @@ void up_irqinitialize(void) } /**************************************************************************** - * Name: arm_decodeirq + * Name: arm_decodeirq, arm_decodefiq (and sam_decodeirq helper). * * Description: * This function is called from the IRQ vector handler in arm_vectors.S. @@ -454,7 +558,7 @@ void up_irqinitialize(void) * ****************************************************************************/ -uint32_t *arm_decodeirq(uint32_t *regs) +static uint32_t *sam_decodeirq(uintptr_t base, uint32_t *regs) { uint32_t irqid; uint32_t ivr; @@ -491,14 +595,14 @@ uint32_t *arm_decodeirq(uint32_t *regs) /* Write in the IVR to support Protect Mode */ - ivr = getreg32(SAM_AIC_IVR); - putreg32(ivr, SAM_AIC_IVR); + ivr = getreg32(base + SAM_AIC_IVR_OFFSET); + putreg32(ivr, base + SAM_AIC_IVR_OFFSET); /* Get the IRQ number from the interrupt status register. NOTE that the * IRQ number is the same is the peripheral ID (PID). */ - irqid = getreg32(SAM_AIC_ISR) & AIC_ISR_MASK; + irqid = getreg32(base + SAM_AIC_ISR_OFFSET) & AIC_ISR_MASK; /* Dispatch the interrupt */ @@ -506,19 +610,46 @@ uint32_t *arm_decodeirq(uint32_t *regs) /* Acknowledge interrupt */ - putreg32(AIC_EOICR_ENDIT, SAM_AIC_EOICR); + putreg32(AIC_EOICR_ENDIT, base + SAM_AIC_EOICR_OFFSET); return regs; } +/* This is the entry point from the ARM IRQ vector handler */ + +uint32_t *arm_decodeirq(uint32_t *regs) +{ + return sam_decodeirq(SAM_AIC_VBASE, regs); +} + +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) +/* This is the entry point from the ARM FIQ vector handler */ + +uint32_t *arm_decodefiq(uint32_t *regs) +{ + /* 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. + */ + + if ((getreg32(SAM_SAIC_CISR) & AIC_CISR_NFIQ) != 0) + { + return sam_fiqhandler(SAM_IRQ_FIQ, regs); + } + else + { + return sam_decodeirq(SAM_SAIC_VBASE, regs); + } +} +#endif + /**************************************************************************** - * Name: up_disable_irq + * Name: up_disable_irq (and sam_disable_irq helper) * * Description: * Disable the IRQ specified by 'irq' * ****************************************************************************/ -void up_disable_irq(int irq) +static void sam_disable_irq(uintptr_t base, int irq) { irqstate_t flags; @@ -530,12 +661,12 @@ void up_disable_irq(int irq) /* Select the register set associated with this irq */ - putreg32(irq, SAM_AIC_SSR); + putreg32(irq, base + SAM_AIC_SSR_OFFSET); /* Disable the interrupt */ - putreg32(AIC_IDCR_INTD, SAM_AIC_IDCR); - sam_dumpaic("disable", irq); + putreg32(AIC_IDCR_INTD, base + SAM_AIC_IDCR_OFFSET); + sam_dumpaic("disable", base, irq); irqrestore(flags); } #ifdef CONFIG_SAMA5_PIO_IRQ @@ -546,18 +677,31 @@ void up_disable_irq(int irq) sam_pioirqdisable(irq); } #endif - sam_dumpaic("disable", irq); +} + +void up_disable_irq(int irq) +{ +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) + if (sam_aic_issecure(irq)) + { + sam_disable_irq(SAM_SAIC_VBASE, irq); + } + else +#endif + { + sam_disable_irq(SAM_AIC_VBASE, irq); + } } /**************************************************************************** - * Name: up_enable_irq + * Name: up_enable_irq (and sam_enable_irq helper) * * Description: * Enable the IRQ specified by 'irq' * ****************************************************************************/ -void up_enable_irq(int irq) +static void sam_enable_irq(uintptr_t base, int irq) { irqstate_t flags; @@ -569,12 +713,12 @@ void up_enable_irq(int irq) /* Select the register set associated with this irq */ - putreg32(irq, SAM_AIC_SSR); + putreg32(irq, base + SAM_AIC_SSR_OFFSET); /* Enable the interrupt */ - putreg32(AIC_IECR_INTEN, SAM_AIC_IECR); - sam_dumpaic("enable", irq); + putreg32(AIC_IECR_INTEN, base + SAM_AIC_IECR_OFFSET); + sam_dumpaic("enable", base, irq); irqrestore(flags); } #ifdef CONFIG_SAMA5_PIO_IRQ @@ -587,6 +731,20 @@ void up_enable_irq(int irq) #endif } +void up_enable_irq(int irq) +{ +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) + if (sam_aic_issecure(irq)) + { + sam_enable_irq(SAM_SAIC_VBASE, irq); + } + else +#endif + { + sam_enable_irq(SAM_AIC_VBASE, irq); + } +} + /**************************************************************************** * Name: up_maskack_irq * @@ -601,7 +759,7 @@ void up_maskack_irq(int irq) } /**************************************************************************** - * Name: up_prioritize_irq + * Name: up_prioritize_irq (and sam_prioritize_irq helper) * * Description: * Set the priority of an IRQ. @@ -612,7 +770,7 @@ void up_maskack_irq(int irq) ****************************************************************************/ #ifdef CONFIG_ARCH_IRQPRIO -int up_prioritize_irq(int irq, int priority) +static int sam_prioritize_irq(uint32_t base, int irq, int priority) { irqstate_t flags; uint32_t regval; @@ -626,32 +784,46 @@ int up_prioritize_irq(int irq, int priority) /* Select the register set associated with this irq */ - putreg32(irq, SAM_AIC_SSR); + putreg32(irq, base + SAM_AIC_SSR_OFFSET); /* Unprotect and write the SMR register */ - putreg32(AIC_WPMR_WPKEY, SAM_AIC_WPMR); + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); /* Set the new priority, preserving the current srctype */ - regval = getreg32(SAM_AIC_SMR); + regval = getreg32(base + SAM_AIC_SMR_OFFSET); regval &= ~AIC_SMR_PRIOR_MASK; regval |= (uint32_t)priority << AIC_SMR_PRIOR_SHIFT; - putreg32(regval, SAM_AIC_SMR); + putreg32(regval, base + SAM_AIC_SMR_OFFSET); /* Restore protection and the interrupt state */ - putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR); - sam_dumpaic("prioritize", irq); + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); + sam_dumpaic("prioritize", base, irq); irqrestore(flags); } return OK; } + +int up_prioritize_irq(int irq, int priority) +{ +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) + if (sam_aic_issecure(irq)) + { + sam_prioritize_irq(SAM_SAIC_VBASE, irq, priority); + } + else +#endif + { + sam_prioritize_irq(SAM_AIC_VBASE, irq, priority); + } +} #endif /**************************************************************************** - * Name: sam_irq_srctype + * Name: sam_irq_srctype (and _sam_irq_srctype helper) * * Description: * irq - Identifies the IRQ source to be configured @@ -659,7 +831,8 @@ int up_prioritize_irq(int irq, int priority) * ****************************************************************************/ -void sam_irq_srctype(int irq, enum sam_srctype_e srctype) +static void _sam_irq_srctype(uintptr_t base, int irq, + enum sam_srctype_e srctype) { irqstate_t flags; uint32_t regval; @@ -672,22 +845,36 @@ void sam_irq_srctype(int irq, enum sam_srctype_e srctype) /* Select the register set associated with this irq */ - putreg32(irq, SAM_AIC_SSR); + putreg32(irq, base + SAM_AIC_SSR_OFFSET); /* Unprotect and write the SMR register */ - putreg32(AIC_WPMR_WPKEY, SAM_AIC_WPMR); + putreg32(AIC_WPMR_WPKEY, base + SAM_AIC_WPMR_OFFSET); /* Set the new srctype, preserving the current priority */ - regval = getreg32(SAM_AIC_SMR); + regval = getreg32(base + SAM_AIC_SMR_OFFSET); regval &= ~AIC_SMR_SRCTYPE_MASK; regval |= (uint32_t)g_srctype[srctype] << AIC_SMR_SRCTYPE_SHIFT; - putreg32(regval, SAM_AIC_SMR); + putreg32(regval, base + SAM_AIC_SMR_OFFSET); /* Restore protection and the interrupt state */ - putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, SAM_AIC_WPMR); - sam_dumpaic("srctype", irq); + putreg32(AIC_WPMR_WPKEY | AIC_WPMR_WPEN, base + SAM_AIC_WPMR_OFFSET); + sam_dumpaic("srctype", base, irq); irqrestore(flags); } + +void sam_irq_srctype(int irq, enum sam_srctype_e srctype) +{ +#if defined(CONFIG_SAMA5_SECURE) && defined(CONFIG_SAMA5_HAVE_SAIC) + if (sam_aic_issecure(irq)) + { + _sam_irq_srctype(SAM_SAIC_VBASE, irq, srctype); + } + else +#endif + { + _sam_irq_srctype(SAM_AIC_VBASE, irq, srctype); + } +} diff --git a/configs/sama5d4-ek/ramtest/defconfig b/configs/sama5d4-ek/ramtest/defconfig index 99e53ac0f3..02b909b98f 100644 --- a/configs/sama5d4-ek/ramtest/defconfig +++ b/configs/sama5d4-ek/ramtest/defconfig @@ -118,6 +118,7 @@ CONFIG_ARMV7A_TOOLCHAIN_CODESOURCERYW=y # CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIL is not set # CONFIG_ARMV7A_TOOLCHAIN_GNU_EABIW is not set # CONFIG_ARMV7A_TOOLCHAIN_GNU_OABI is not set +# CONFIG_ARMV7A_DECODEFIQ is not set # # SAMA5 Configuration Options @@ -145,6 +146,7 @@ CONFIG_SAMA5_HAVE_SFC=y CONFIG_SAMA5_HAVE_SPI2=y CONFIG_SAMA5_HAVE_TC1=y CONFIG_SAMA5_HAVE_TC2=y +CONFIG_SAMA5_HAVE_TRUSTZONE=y CONFIG_SAMA5_HAVE_TWI3=y CONFIG_SAMA5_HAVE_VDEC=y # CONFIG_ARCH_CHIP_SAMA5D3 is not set @@ -211,6 +213,7 @@ CONFIG_SAMA5_USART3=y # CONFIG_SAMA5_FUSE is not set CONFIG_SAMA5_MPDDRC=y # CONFIG_SAMA5_VDEC is not set +# CONFIG_SAMA5_SECURE is not set # CONFIG_SAMA5_PIO_IRQ is not set #