blob: 2a5c1a1941c2932d96741436bd3a36bfb4baafda [file] [log] [blame]
/****************************************************************************
* arch/arm/src/armv8-r/arm_gic.h
*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_ARMV8_R_ARM_GIC_H
#define __ARCH_ARM_SRC_ARMV8_R_ARM_GIC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <arch/irq.h>
#include <arch/chip/chip.h>
#include "arm_internal.h"
#include "arm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* GIC Distributor register Interface Base Addresses
* Arm® Generic Interrupt Controller Architecture Specification
* GIC architecture version 3 and version 4
*/
#define GIC_DIST_BASE CONFIG_GICD_BASE
#define GICD_CTLR (GIC_DIST_BASE + 0x0)
#define GICD_TYPER (GIC_DIST_BASE + 0x4)
#define GICD_IIDR (GIC_DIST_BASE + 0x8)
#define GICD_STATUSR (GIC_DIST_BASE + 0x10)
#define GICD_SETSPI_NSR (GIC_DIST_BASE + 0x40)
#define GICD_CLRSPI_NSR (GIC_DIST_BASE + 0x48)
#define GICD_SETSPI_SR (GIC_DIST_BASE + 0x50)
#define GICD_CLRSPI_SR (GIC_DIST_BASE + 0x58)
#define GICD_IGROUPRn (GIC_DIST_BASE + 0x80)
#define GICD_ISENABLERn (GIC_DIST_BASE + 0x100)
#define GICD_ICENABLERn (GIC_DIST_BASE + 0x180)
#define GICD_ISPENDRn (GIC_DIST_BASE + 0x200)
#define GICD_ICPENDRn (GIC_DIST_BASE + 0x280)
#define GICD_ISACTIVERn (GIC_DIST_BASE + 0x300)
#define GICD_ICACTIVERn (GIC_DIST_BASE + 0x380)
#define GICD_IPRIORITYRn (GIC_DIST_BASE + 0x400)
#define GICD_ITARGETSRn (GIC_DIST_BASE + 0x800)
#define GICD_ICFGRn (GIC_DIST_BASE + 0xc00)
#define GICD_SGIR (GIC_DIST_BASE + 0xf00)
#define GICD_IDREGS (GIC_DIST_BASE + 0xFFD0)
#define GICD_PIDR2 (GIC_DIST_BASE + 0xFFE8)
/* Offsets from GICD base or GICR(n) SGI_base */
#define GIC_DIST_IGROUPR 0x0080
#define GIC_DIST_ISENABLER 0x0100
#define GIC_DIST_ICENABLER 0x0180
#define GIC_DIST_ISPENDR 0x0200
#define GIC_DIST_ICPENDR 0x0280
#define GIC_DIST_ISACTIVER 0x0300
#define GIC_DIST_ICACTIVER 0x0380
#define GIC_DIST_IPRIORITYR 0x0400
#define GIC_DIST_ITARGETSR 0x0800
#define GIC_DIST_ICFGR 0x0c00
#define GIC_DIST_IGROUPMODR 0x0d00
#define GIC_DIST_SGIR 0x0f00
/* GICD GICR common access macros */
#define IGROUPR(base, n) (base + GIC_DIST_IGROUPR + (n) * 4)
#define ISENABLER(base, n) (base + GIC_DIST_ISENABLER + (n) * 4)
#define ICENABLER(base, n) (base + GIC_DIST_ICENABLER + (n) * 4)
#define ISPENDR(base, n) (base + GIC_DIST_ISPENDR + (n) * 4)
#define ICPENDR(base, n) (base + GIC_DIST_ICPENDR + (n) * 4)
#define IPRIORITYR(base, n) (base + GIC_DIST_IPRIORITYR + n)
#define ITARGETSR(base, n) (base + GIC_DIST_ITARGETSR + (n) * 4)
#define ICFGR(base, n) (base + GIC_DIST_ICFGR + (n) * 4)
#define IGROUPMODR(base, n) (base + GIC_DIST_IGROUPMODR + (n) * 4)
/* GICD_PIDR2 : Peripheral ID2 Register
* bit assignments
* [31:8] - IMPLEMENTATION DEFINED
* [7:4] ArchRev 0x1. GICv1.
* 0x2. GICv2.
* 0x3. GICv3.
* 0x4. GICv4.
* [3:0] - IMPLEMENTATION DEFINED.
*/
#define GICD_PIDR2_ARCH_MASK 0xf0
#define GICD_PIDR2_ARCH_GICV2 0x20
#define GICD_PIDR2_ARCH_GICV3 0x30
#define GICD_PIDR2_ARCH_GICV4 0x40
/* GICD_TYPER : Interrupt Controller Type Register
* Arm® Generic Interrupt Controller Architecture Specification
* GIC architecture version 3 and version 4
*/
#define GICD_TYPER_RSS BIT(26)
#define GICD_TYPER_LPIS BIT(17)
#define GICD_TYPER_MBIS BIT(16)
#define GICD_TYPER_ESPI BIT(8)
#define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1)
#define GICD_TYPER_NUM_LPIS(typer) ((((typer) >> 11) & 0x1f) + 1)
#define GICD_TYPER_SPIS(typer) ((((typer) & 0x1f) + 1) * 32)
#define GICD_TYPER_ESPIS(typer) \
(((typer) & GICD_TYPER_ESPI) ? GICD_TYPER_SPIS((typer) >> 27) : 0)
/* Common Helper Constants */
#define GIC_SGI_INT_BASE 0
#define GIC_PPI_INT_BASE 16
#define GIC_IS_SGI(intid) (((intid) >= GIC_SGI_INT_BASE) && \
((intid) < GIC_PPI_INT_BASE))
#define GIC_SPI_INT_BASE 32
#define GIC_NUM_INTR_PER_REG 32
#define GIC_NUM_CFG_PER_REG 16
#define GIC_NUM_PRI_PER_REG 4
/* GIC idle priority : value '0xff' will allow all interrupts */
#define GIC_IDLE_PRIO 0xff
/* Priority levels 0:255 */
#define GIC_PRI_MASK 0xff
/* '0xa0'is used to initialize each interrtupt default priority.
* This is an arbitrary value in current context.
* Any value '0x80' to '0xff' will work for both NS and S state.
* The values of individual interrupt and default has to be chosen
* carefully if PMR and BPR based nesting and preemption has to be done.
*/
#define GIC_INT_DEF_PRI_X4 0xa0a0a0a0
/* GICD_CTLR : Distributor Control Register
*
* [31](RO) RWP Register Write Pending:
* -- 0 No register write in progress
* -- 1 Register write in progress
* [30:8] - Reserved -
* [7](RW) E1NWF Enable 1 of N Wakeup Functionality 0
* [6](RO) DS Disable Security status:
* -- 0 The gicd_ctlr_ds signal was LOW when the GIC
* exited reset. Therefore, the Distributor supports
* two Security states and Non-secure accesses cannot
* access and modify registers that control Group 0
* interrupts.
* -- 1 The gicd_ctlr_ds signal was HIGH when the GIC
* exited reset. Therefore, the Distributor only supports
* a single Security state and Non-secure accesses
* can access and modify registers that control
* Group 0 interrupts.
* [5](RO) ARE_NS Affinity Routing Enable, Non-secure state
* [4](RO) ARE_S Affinity Routing Enable, Secure state
* [3] - Reserved -
* [2](RW) EnableGrp1S Enable Secure Group 1 interrupts
* [1](RW) EnableGrp1NS Enable Non-secure Group 1 interrupts
* [0](RW) EnableGrp0 Enable Group 0 interrupts
*/
#define GICD_CTLR_ENABLE_G0 0
#define GICD_CTLR_ENABLE_G1NS 1
#define GICD_CTLR_ENABLE_G1S 2
#define GICD_CTRL_ARE_S 4
#define GICD_CTRL_ARE_NS 5
#define GICD_CTRL_DS 6
#define GICD_CGRL_E1NWF 7
/* GICD_CTLR Register write progress bit */
#define GICD_CTLR_RWP 31
/* GICR_CTLR */
#define GICR_CTLR_ENABLE_LPIS BIT(0)
#define GICR_CTLR_RWP 3
/* GICD_TYPER.ITLinesNumber 0:4 */
#define GICD_TYPER_ITLINESNUM_MASK 0x1f
/* GICR: Re-Distributor registers, offsets from RD_base(n) */
#define GICR_CTLR 0x0000
#define GICR_IIDR 0x0004
#define GICR_TYPER 0x0008
#define GICR_STATUSR 0x0010
#define GICR_WAKER 0x0014
#define GICR_PWRR 0x0024
#define GICR_SETLPIR 0x0040
#define GICR_CLRLPIR 0x0048
#define GICR_PROPBASER 0x0070
#define GICR_PENDBASER 0x0078
#define GICR_INVLPIR 0x00A0
#define GICR_INVALLR 0x00B0
#define GICR_SYNCR 0x00C0
#define GICR_MOVLPIR 0x0100
#define GICR_MOVALLR 0x0110
#define GICR_IDREGS 0xFFD0
#define GICR_PIDR2 0xFFE8
/* GICR_PIDR2 : Peripheral ID2 Register
* bit assignments are the same as those for GICD_PIDR2)
* [31:8] - IMPLEMENTATION DEFINED
* [7:4] ArchRev 0x1. GICv1.
* 0x2. GICv2.
* 0x3. GICv3.
* 0x4. GICv4.
* [3:0] - IMPLEMENTATION DEFINED.
*/
#define GICR_PIDR2_ARCH_MASK 0xf0
#define GICR_PIDR2_ARCH_GICV3 0x30
#define GICR_PIDR2_ARCH_GICV4 0x40
/* GICR_TYPER : Redistributor Type Register
* Arm® Generic Interrupt Controller Architecture Specification
* GIC architecture version 3 and version 4
* chapter 9.11.35 for detail descriptions
*/
#define GICR_TYPER_PLPIS BIT(0)
#define GICR_TYPER_VLPIS BIT(1)
#define GICR_TYPER_DIRECTLPIS BIT(3)
#define GICR_TYPER_LAST BIT(4)
/* GICR_WAKER */
#define GICR_WAKER_PS 1
#define GICR_WAKER_CA 2
/* SGI base is at 64K offset from Redistributor */
#define GICR_SGI_BASE_OFF 0x10000
/* GICD_ICFGR */
#define GICD_ICFGR_MASK BIT_MASK(2)
#define GICD_ICFGR_TYPE BIT(1)
/* BIT(0) reserved for IRQ_ZERO_LATENCY */
#define IRQ_TYPE_LEVEL BIT(1)
#define IRQ_TYPE_EDGE BIT(2)
#define GIC_SPI_INT_BASE 32
#define GIC_SPI_MAX_INTID 1019
#define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && \
((intid) <= GIC_SPI_MAX_INTID))
/* GITCD_IROUTER */
#define GIC_DIST_IROUTER 0x6000
#define IROUTER(base, n) (base + GIC_DIST_IROUTER + (n) * 8)
/* BIT(0) reserved for IRQ_ZERO_LATENCY */
#define IRQ_TYPE_LEVEL BIT(1)
#define IRQ_TYPE_EDGE BIT(2)
#define IRQ_DEFAULT_PRIORITY 0xa0
#define GIC_IRQ_SGI0 0
#define GIC_IRQ_SGI1 1
#define GIC_IRQ_SGI2 2
#define GIC_IRQ_SGI3 3
#define GIC_IRQ_SGI4 4
#define GIC_IRQ_SGI5 5
#define GIC_IRQ_SGI6 6
#define GIC_IRQ_SGI7 7
#define GIC_IRQ_SGI8 8
#define GIC_IRQ_SGI9 9
#define GIC_IRQ_SGI10 10
#define GIC_IRQ_SGI11 11
#define GIC_IRQ_SGI12 12
#define GIC_IRQ_SGI13 13
#define GIC_IRQ_SGI14 14
#define GIC_IRQ_SGI15 15
/* register constants */
#define ICC_SRE_ELX_SRE_BIT BIT(0)
#define ICC_SRE_ELX_DFB_BIT BIT(1)
#define ICC_SRE_ELX_DIB_BIT BIT(2)
#define ICC_SRE_EL3_EN_BIT BIT(3)
/* ICC SGI macros */
#define SGIR_TGT_MASK (0xffff)
#define SGIR_AFF1_SHIFT (16)
#define SGIR_AFF2_SHIFT (32)
#define SGIR_AFF3_SHIFT (48)
#define SGIR_AFF_MASK (0xf)
#define SGIR_INTID_SHIFT (24)
#define SGIR_INTID_MASK (0xf)
#define SGIR_IRM_SHIFT (40)
#define SGIR_IRM_MASK (0x1)
#define SGIR_IRM_TO_AFF (0)
#define SGIR_IRM_TO_ALL (1)
#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \
((((uint64_t)(_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \
(((uint64_t)(_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \
(((uint64_t)(_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \
(((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \
(((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
((_tgt) & SGIR_TGT_MASK))
#ifdef CONFIG_ARCH_TRUSTZONE_SECURE
# define GIC_SMP_CPUSTART GIC_IRQ_SGI9
# define GIC_SMP_CALL GIC_IRQ_SGI10
# define GIC_SMP_SCHED GIC_IRQ_SGI11
#else
# define GIC_SMP_CPUSTART GIC_IRQ_SGI1
# define GIC_SMP_CALL GIC_IRQ_SGI2
# define GIC_SMP_SCHED GIC_IRQ_SGI3
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
bool arm_gic_irq_is_enabled(unsigned int intid);
int arm_gic_initialize(void);
void arm_gic_irq_set_priority(unsigned int intid, unsigned int prio,
uint32_t flags);
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
void arm_gic_set_group(unsigned int intid, unsigned int group);
#endif
int arm_gic_irq_trigger(unsigned int intid, uint32_t flags);
int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t target_list);
#ifdef CONFIG_SMP
int arm_smp_sched_handler(int irq, void *context, void *arg);
void arm_gic_secondary_init(void);
#endif
/****************************************************************************
* Name: arm_get_mpid
*
* Description:
* The function from cpu index to get cpu mpid which is reading
* from mpidr_el1 register. Different ARM64 Core will use different
* Affn define, the mpidr_el1 value is not CPU number, So we need
* to change CPU number to mpid and vice versa
*
****************************************************************************/
#ifdef CONFIG_SMP
static inline uint64_t arm_get_mpid(int cpu)
{
return CORE_TO_MPID(cpu, 0);
}
#else
# define arm_get_mpid(cpu) GET_MPIDR()
#endif /* CONFIG_SMP */
#endif /* __ARCH_ARM_SRC_ARMV8_R_ARM_GIC_H */