/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __SELFTESTS_GIC_V5_H #define __SELFTESTS_GIC_V5_H #include #include #include #include "processor.h" /* GIC component base address is guest PA space */ #define GICV5_IRS_CONFIG_BASE_GPA 0x8000000ULL #define GICV5_IRS_CONFIG_BASE_GVA ((volatile void *)GICV5_IRS_CONFIG_BASE_GPA) #define GICV5_IRS_SIZE 0x20000 #define GICV5_IRS_ALIGN 0x10000 /* * IRS register offsets. Keep this selftest copy scoped to the offsets and * fields exercised by the userspace API tests. */ #define GICV5_IRS_IDR0 0x0000 #define GICV5_IRS_IDR1 0x0004 #define GICV5_IRS_IDR2 0x0008 #define GICV5_IRS_IDR3 0x000c #define GICV5_IRS_IDR4 0x0010 #define GICV5_IRS_IDR5 0x0014 #define GICV5_IRS_IDR6 0x0018 #define GICV5_IRS_IDR7 0x001c #define GICV5_IRS_IIDR 0x0040 #define GICV5_IRS_AIDR 0x0044 #define GICV5_IRS_CR0 0x0080 #define GICV5_IRS_CR1 0x0084 #define GICV5_IRS_SYNCR 0x00c0 #define GICV5_IRS_SYNC_STATUSR 0x00c4 #define GICV5_IRS_SPI_VMR 0x0100 #define GICV5_IRS_SPI_SELR 0x0108 #define GICV5_IRS_SPI_DOMAINR 0x010c #define GICV5_IRS_SPI_RESAMPLER 0x0110 #define GICV5_IRS_SPI_CFGR 0x0114 #define GICV5_IRS_SPI_STATUSR 0x0118 #define GICV5_IRS_PE_SELR 0x0140 #define GICV5_IRS_PE_STATUSR 0x0144 #define GICV5_IRS_PE_CR0 0x0148 #define GICV5_IRS_IST_BASER 0x0180 #define GICV5_IRS_IST_CFGR 0x0190 #define GICV5_IRS_IST_STATUSR 0x0194 #define GICV5_IRS_MAP_L2_ISTR 0x01c0 #define GICV5_IRS_VMT_BASER 0x0200 #define GICV5_IRS_VMT_CFGR 0x0210 #define GICV5_IRS_VMT_STATUSR 0x0214 #define GICV5_IRS_VPE_SELR 0x0240 #define GICV5_IRS_VPE_DBR 0x0248 #define GICV5_IRS_VPE_HPPIR 0x0250 #define GICV5_IRS_VPE_CR0 0x0258 #define GICV5_IRS_VPE_STATUSR 0x025c #define GICV5_IRS_VM_DBR 0x0280 #define GICV5_IRS_VM_SELR 0x0288 #define GICV5_IRS_VM_STATUSR 0x028c #define GICV5_IRS_VMAP_L2_VMTR 0x02c0 #define GICV5_IRS_VMAP_VMR 0x02c8 #define GICV5_IRS_VMAP_VISTR 0x02d0 #define GICV5_IRS_VMAP_L2_VISTR 0x02d8 #define GICV5_IRS_VMAP_VPER 0x02e0 #define GICV5_IRS_SAVE_VMR 0x0300 #define GICV5_IRS_SAVE_VM_STATUSR 0x0308 #define GICV5_IRS_MEC_IDR 0x0340 #define GICV5_IRS_MEC_MECID_R 0x0344 #define GICV5_IRS_MPAM_IDR 0x0380 #define GICV5_IRS_MPAM_PARTID_R 0x0384 #define GICV5_IRS_SWERR_STATUSR 0x03c0 #define GICV5_IRS_SWERR_SYNDROMER0 0x03c8 #define GICV5_IRS_SWERR_SYNDROMER1 0x03d0 #define GICV5_IRS_IDR0_SETLPI BIT(9) #define GICV5_IRS_IDR0_INT_DOM GENMASK(1, 0) #define GICV5_IRS_IDR0_INT_DOM_SECURE 0b00 #define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) #define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15) #define GICV5_IRS_IDR2_ISTMD BIT(14) #define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11) #define GICV5_IRS_IDR2_IST_LEVELS BIT(10) #define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6) #define GICV5_IRS_IDR2_LPI BIT(5) #define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0) #define GICV5_IRS_CR0_IDLE BIT(1) #define GICV5_IRS_CR0_IRSEN BIT(0) #define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0) #define GICV5_IRS_SPI_CFGR_TM BIT(0) #define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) #define GICV5_IRS_PE_STATUSR_IDLE BIT(0) #define GICV5_IRS_IST_STATUSR_IDLE BIT(0) #define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6) #define GICV5_IRS_IST_BASER_VALID BIT_ULL(0) #define GICV5_IRS_IST_BASER_ADDR_SHIFT 6ULL #define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16) #define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7) #define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5) #define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0) #define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00 #define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01 #define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10 /* * Definitions for GICv5 instructions for the Current Domain */ #define GICV5_OP_GIC_CDAFF sys_insn(1, 0, 12, 1, 3) #define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) #define GICV5_OP_GIC_CDDIS sys_insn(1, 0, 12, 1, 0) #define GICV5_OP_GIC_CDHM sys_insn(1, 0, 12, 2, 1) #define GICV5_OP_GIC_CDEN sys_insn(1, 0, 12, 1, 1) #define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) #define GICV5_OP_GIC_CDPEND sys_insn(1, 0, 12, 1, 4) #define GICV5_OP_GIC_CDPRI sys_insn(1, 0, 12, 1, 2) #define GICV5_OP_GIC_CDRCFG sys_insn(1, 0, 12, 1, 5) #define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0) #define GICV5_OP_GICR_CDNMIA sys_insn(1, 0, 12, 3, 1) /* Definitions for GIC CDAFF */ #define GICV5_GIC_CDAFF_IAFFID_MASK GENMASK_ULL(47, 32) #define GICV5_GIC_CDAFF_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDAFF_IRM_MASK BIT_ULL(28) #define GICV5_GIC_CDAFF_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDDI */ #define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDDIS */ #define GICV5_GIC_CDDIS_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDDIS_TYPE(r) FIELD_GET(GICV5_GIC_CDDIS_TYPE_MASK, r) #define GICV5_GIC_CDDIS_ID_MASK GENMASK_ULL(23, 0) #define GICV5_GIC_CDDIS_ID(r) FIELD_GET(GICV5_GIC_CDDIS_ID_MASK, r) /* Definitions for GIC CDEN */ #define GICV5_GIC_CDEN_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDEN_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDHM */ #define GICV5_GIC_CDHM_HM_MASK BIT_ULL(32) #define GICV5_GIC_CDHM_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDHM_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDPEND */ #define GICV5_GIC_CDPEND_PENDING_MASK BIT_ULL(32) #define GICV5_GIC_CDPEND_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDPEND_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDPRI */ #define GICV5_GIC_CDPRI_PRIORITY_MASK GENMASK_ULL(39, 35) #define GICV5_GIC_CDPRI_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDPRI_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GIC CDRCFG */ #define GICV5_GIC_CDRCFG_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDRCFG_ID_MASK GENMASK_ULL(23, 0) /* Definitions for GICR CDIA */ #define GICV5_GICR_CDIA_VALID_MASK BIT_ULL(32) #define GICV5_GICR_CDIA_VALID(r) FIELD_GET(GICV5_GICR_CDIA_VALID_MASK, r) #define GICV5_GICR_CDIA_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GICR_CDIA_ID_MASK GENMASK_ULL(23, 0) #define GICV5_GICR_CDIA_INTID GENMASK_ULL(31, 0) /* Definitions for GICR CDNMIA */ #define GICV5_GICR_CDNMIA_VALID_MASK BIT_ULL(32) #define GICV5_GICR_CDNMIA_VALID(r) FIELD_GET(GICV5_GICR_CDNMIA_VALID_MASK, r) #define GICV5_GICR_CDNMIA_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GICR_CDNMIA_ID_MASK GENMASK_ULL(23, 0) #define GICV5_HWIRQ_TYPE GENMASK_ULL(31, 29) #define GICV5_HWIRQ_ID GENMASK_ULL(23, 0) #define GICV5_HWIRQ_TYPE_LPI 0x2 #define GICV5_HWIRQ_TYPE_SPI 0x3 #define gicr_insn(insn) read_sysreg_s(GICV5_OP_GICR_##insn) #define gic_insn(v, insn) write_sysreg_s(v, GICV5_OP_GIC_##insn) #define __GIC_BARRIER_INSN(op0, op1, CRn, CRm, op2, Rt) \ __emit_inst(0xd5000000 | \ sys_insn((op0), (op1), (CRn), (CRm), (op2)) | \ ((Rt) & 0x1f)) #define GSB_SYS_BARRIER_INSN __GIC_BARRIER_INSN(1, 0, 12, 0, 0, 31) #define GSB_ACK_BARRIER_INSN __GIC_BARRIER_INSN(1, 0, 12, 0, 1, 31) #define gsb_ack() asm volatile(GSB_ACK_BARRIER_INSN : : : "memory") #define gsb_sys() asm volatile(GSB_SYS_BARRIER_INSN : : : "memory") #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) #define GICV5_IRQ_DEFAULT_PRI 0b10000 #define GICV5_ARCH_PPI_SW_PPI 0x3 void gicv5_ppi_priority_init(void) { write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR0_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR1_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR2_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR3_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR4_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR5_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR6_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR7_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR8_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR9_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR10_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR11_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR12_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR13_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR14_EL1); write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR15_EL1); /* * Context syncronization required to make sure system register writes * effects are synchronised. */ isb(); } void gicv5_cpu_disable_interrupts(void) { u64 cr0; cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 0); write_sysreg_s(cr0, SYS_ICC_CR0_EL1); } void gicv5_cpu_enable_interrupts(void) { u64 cr0, pcr; write_sysreg_s(0, SYS_ICC_PPI_ENABLER0_EL1); write_sysreg_s(0, SYS_ICC_PPI_ENABLER1_EL1); gicv5_ppi_priority_init(); pcr = FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_DEFAULT_PRI); write_sysreg_s(pcr, SYS_ICC_PCR_EL1); cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 1); write_sysreg_s(cr0, SYS_ICC_CR0_EL1); } #endif