diff --git a/arch/arm/src/armv8-m/arm_secure_irq.c b/arch/arm/src/armv8-m/arm_secure_irq.c new file mode 100644 index 00000000000..59dc5993180 --- /dev/null +++ b/arch/arm/src/armv8-m/arm_secure_irq.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/arm/src/armv8-m/arm_secure_irq.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 + +#include +#include + +#include +#include + +#include "arm_arch.h" +#include "nvic.h" + +#ifdef CONFIG_ARCH_HAVE_TRUSTZONE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_set_secure_irq + * + * Description: + * Secure an IRQ + * + ****************************************************************************/ + +void up_secure_irq(int irq, bool secure) +{ + uint32_t regaddr; + uint32_t regval; + int shift; + + DEBUGASSERT(irq >= NVIC_IRQ_FIRST && irq < NR_IRQS); + + irq -= NVIC_IRQ_FIRST; + regaddr = NVIC_IRQ_TARGET(irq); + + regval = getreg32(regaddr); + shift = irq & 0x1f; + regval &= ~(1 << shift); + regval |= !secure << shift; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: up_secure_irq_all + * + * Description: + * Secure all IRQ + * + ****************************************************************************/ + +void up_secure_irq_all(bool secure) +{ + int i; + + for (i = 0; i <= NR_IRQS - NVIC_IRQ_FIRST; i += 32) + { + putreg32(secure ? 0x0 : 0xffffffff, NVIC_IRQ_TARGET(i)); + } +} + +#endif /* CONFIG_ARCH_HAVE_TRUSTZONE */ diff --git a/arch/arm/src/armv8-m/nvic.h b/arch/arm/src/armv8-m/nvic.h index 98e5957004f..7817195acee 100644 --- a/arch/arm/src/armv8-m/nvic.h +++ b/arch/arm/src/armv8-m/nvic.h @@ -118,6 +118,16 @@ #define NVIC_IRQ192_223_ACTIVE_OFFSET 0x0318 /* IRQ 192-223 active bit register */ #define NVIC_IRQ224_239_ACTIVE_OFFSET 0x031c /* IRQ 224-239 active bit register */ +#define NVIC_IRQ_TARGET_OFFSET(n) (0x0380 + 4*((n) >> 5)) +#define NVIC_IRQ0_31_TARGET_OFFSET 0x0380 /* IRQ 0-31 target non-secure register */ +#define NVIC_IRQ32_63_TARGET_OFFSET 0x0384 /* IRQ 32-63 target non-secure register */ +#define NVIC_IRQ64_95_TARGET_OFFSET 0x0388 /* IRQ 64-95 target non-secure register */ +#define NVIC_IRQ96_127_TARGET_OFFSET 0x038c /* IRQ 96-127 target non-secure register */ +#define NVIC_IRQ128_159_TARGET_OFFSET 0x0390 /* IRQ 128-159 target non-secure register */ +#define NVIC_IRQ160_191_TARGET_OFFSET 0x0394 /* IRQ 160-191 target non-secure register */ +#define NVIC_IRQ192_223_TARGET_OFFSET 0x0398 /* IRQ 192-223 target non-secure register */ +#define NVIC_IRQ224_239_TARGET_OFFSET 0x039c /* IRQ 224-239 target non-secure register */ + #define NVIC_IRQ_PRIORITY_OFFSET(n) (0x0400 + 4*((n) >> 2)) #define NVIC_IRQ0_3_PRIORITY_OFFSET 0x0400 /* IRQ 0-3 priority register */ #define NVIC_IRQ4_7_PRIORITY_OFFSET 0x0404 /* IRQ 4-7 priority register */ @@ -315,6 +325,16 @@ #define NVIC_IRQ192_223_ACTIVE (ARMV8M_NVIC_BASE + NVIC_IRQ192_223_ACTIVE_OFFSET) #define NVIC_IRQ224_239_ACTIVE (ARMV8M_NVIC_BASE + NVIC_IRQ224_239_ACTIVE_OFFSET) +#define NVIC_IRQ_TARGET(n) (ARMV8M_NVIC_BASE + NVIC_IRQ_TARGET_OFFSET(n)) +#define NVIC_IRQ0_31_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ0_31_TARGET_OFFSET) +#define NVIC_IRQ32_63_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ32_63_TARGET_OFFSET) +#define NVIC_IRQ64_95_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ64_95_TARGET_OFFSET) +#define NVIC_IRQ96_127_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ96_127_TARGET_OFFSET) +#define NVIC_IRQ128_159_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ128_159_TARGET_OFFSET) +#define NVIC_IRQ160_191_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ160_191_TARGET_OFFSET) +#define NVIC_IRQ192_223_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ192_223_TARGET_OFFSET) +#define NVIC_IRQ224_239_TARGET (ARMV8M_NVIC_BASE + NVIC_IRQ224_239_TARGET_OFFSET) + #define NVIC_IRQ_PRIORITY(n) (ARMV8M_NVIC_BASE + NVIC_IRQ_PRIORITY_OFFSET(n)) #define NVIC_IRQ0_3_PRIORITY (ARMV8M_NVIC_BASE + NVIC_IRQ0_3_PRIORITY_OFFSET) #define NVIC_IRQ4_7_PRIORITY (ARMV8M_NVIC_BASE + NVIC_IRQ4_7_PRIORITY_OFFSET) diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 517ec3ff8dc..76fc49278c0 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -1458,6 +1458,30 @@ void up_trigger_irq(int irq); int up_prioritize_irq(int irq, int priority); #endif +#ifdef CONFIG_ARCH_HAVE_TRUSTZONE + +/**************************************************************************** + * Name: up_set_secure_irq + * + * Description: + * Secure an IRQ + * + ****************************************************************************/ + +void up_secure_irq(int irq, bool secure); + +/**************************************************************************** + * Name: up_secure_irq_all + * + * Description: + * Secure all IRQ + * + ****************************************************************************/ + +void up_secure_irq_all(bool secure); + +#endif + /**************************************************************************** * Function: up_timer_initialize *