1 /* 2 * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef GICV5_H 8 #define GICV5_H 9 10 #ifndef __ASSEMBLER__ 11 #include <stdbool.h> 12 #include <stdint.h> 13 14 #include <lib/mmio.h> 15 #endif 16 17 #include <lib/utils_def.h> 18 19 /* Interrupt Domain definitions */ 20 #define INTDMN_S 0 21 #define INTDMN_NS 1 22 #define INTDMN_EL3 2 23 #define INTDMN_RL 3 24 25 /* Trigger modes */ 26 #define TM_EDGE 0 27 #define TM_LEVEL 1 28 29 /* Architected PPI numbers */ 30 #define PPI_TRBIRQ 31 31 #define PPI_CNTP 30 32 #define PPI_CNTPS 29 33 #define PPI_CNTHV 28 34 #define PPI_CNTV 27 35 #define PPI_CNTHP 26 36 #define PPI_GICMNT 25 37 #define PPI_CTIIRQ 24 38 #define PPI_PMUIRQ 23 39 #define PPI_COMMIRQ 22 40 #define PPI_PMBIRQ 21 41 #define PPI_CNTHPS 20 42 #define PPI_CNTHVS 19 43 #define PPI_DB_NS 2 44 #define PPI_DB_RL 1 45 #define PPI_DB_S 0 46 47 /* Register fields common to all IRI components. 48 * They have the same name and offset in every config frame */ 49 #define IRI_AIDR_COMPONENT_SHIFT 8 50 #define IRI_AIDR_COMPONENT_WIDTH 4 51 #define IRI_AIDR_COMPONENT_IRS 0 52 #define IRI_AIDR_COMPONENT_ITS 1 53 #define IRI_AIDR_COMPONENT_IWB 2 54 #define IRI_AIDR_ARCH_MAJOR_SHIFT 4 55 #define IRI_AIDR_ARCH_MAJOR_WIDTH 4 56 #define IRI_AIDR_ARCH_MAJOR_V5 0 57 #define IRI_AIDR_ARCH_MINOR_SHIFT 0 58 #define IRI_AIDR_ARCH_MINOR_WIDTH 4 59 #define IRI_AIDR_ARCH_MINOR_P0 0 60 61 /* IRS register fields */ 62 #define IRS_IDR6_SPI_IRS_RANGE_SHIFT 0 63 #define IRS_IDR6_SPI_IRS_RANGE_WIDTH 24 64 #define IRS_IDR7_SPI_BASE_SHIFT 0 65 #define IRS_IDR7_SPI_BASE_WIDTH 24 66 67 #define IRS_SPI_STATUSR_IDLE_BIT BIT(0) 68 #define IRS_SPI_STATUSR_V_BIT BIT(1) 69 70 /* IWB register fields */ 71 #define IWB_IDR0_DOMAINS_SHIFT 11 72 #define IWB_IDR0_DOMAINS_WIDTH 4 73 #define IWB_IDR0_IWRANGE_SHIFT 0 74 #define IWB_IDR0_IWRANGE_WIDTH 10 75 76 #define IWB_CR0_IWBEN_BIT BIT(0) 77 #define IWB_CR0_IDLE_BIT BIT(1) 78 79 #define IWB_WENABLE_STATUSR_IDLE_BIT BIT(0) 80 #define IWB_WDOMAIN_STATUSR_IDLE_BIT BIT(0) 81 82 #define IWB_WDOMAINR_DOMAINX_MASK 0x3 83 84 #ifndef __ASSEMBLER__ 85 86 #define _PPI_FIELD_SHIFT(_REG, _ppi_id) \ 87 ((_ppi_id % (ICC_PPI_##_REG##_COUNT)) * (64 / ICC_PPI_##_REG##_COUNT)) 88 89 #define write_icc_ppi_domainr(_var, _ppi_id, _value) \ 90 do { \ 91 _var |= (uint64_t)_value << _PPI_FIELD_SHIFT(DOMAINR, _ppi_id);\ 92 } while (false) 93 94 95 #define DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset) \ 96 static inline void write_##_name(uintptr_t base, uint32_t val) \ 97 { \ 98 mmio_write_32(base + _offset, val); \ 99 } 100 101 #define DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \ 102 static inline uint32_t read_##_name(uintptr_t base) \ 103 { \ 104 return mmio_read_32(base + _offset); \ 105 } 106 107 #define DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset) \ 108 static inline void write_##_name(uintptr_t base, uint16_t index, uint32_t val) \ 109 { \ 110 mmio_write_32(base + _offset + (index * sizeof(uint32_t)), val); \ 111 } 112 113 #define DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset) \ 114 static inline uint32_t read_##_name(uintptr_t base, uint16_t index) \ 115 { \ 116 return mmio_read_32(base + _offset + (index * sizeof(uint32_t))); \ 117 } 118 119 #define DEFINE_GICV5_MMIO_RW_FUNCS(_name, _offset) \ 120 DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \ 121 DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset) 122 123 #define DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(_name, _offset) \ 124 DEFINE_GICV5_MMIO_READ_INDEXED_FUNC(_name, _offset) \ 125 DEFINE_GICV5_MMIO_WRITE_INDEXED_FUNC(_name, _offset) 126 127 DEFINE_GICV5_MMIO_READ_FUNC(iri_aidr, 0x44) 128 129 DEFINE_GICV5_MMIO_READ_FUNC(iwb_idr0, 0x00) 130 DEFINE_GICV5_MMIO_RW_FUNCS( iwb_cr0, 0x80) 131 DEFINE_GICV5_MMIO_READ_FUNC(iwb_wenable_statusr, 0xc0) 132 DEFINE_GICV5_MMIO_READ_FUNC(iwb_wdomain_statusr, 0xc4) 133 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wenabler, 0x2000) 134 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wtmr, 0x4000) 135 DEFINE_GICV5_MMIO_RW_INDEXED_FUNCS(iwb_wdomainr, 0x8000) 136 137 DEFINE_GICV5_MMIO_READ_FUNC(irs_idr6, 0x0018) 138 DEFINE_GICV5_MMIO_READ_FUNC(irs_idr7, 0x001c) 139 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_selr, 0x0108) 140 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_domainr, 0x010c) 141 DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_cfgr, 0x0114) 142 DEFINE_GICV5_MMIO_READ_FUNC(irs_spi_statusr, 0x0118) 143 144 #define WAIT_FOR_IDLE(base, reg, reg_up) \ 145 do { \ 146 while ((read_##reg(base) & reg_up##_IDLE_BIT) == 0U) {} \ 147 } while (0) 148 149 /* wait for IDLE but also check the V bit was set */ 150 #define WAIT_FOR_VIDLE(base, reg, reg_up) \ 151 do { \ 152 uint32_t val; \ 153 while (((val = read_##reg(base)) & reg_up##_IDLE_BIT) == 0U) {} \ 154 assert((val & reg##_V_BIT) != 0U); \ 155 } while (0) 156 157 #define WAIT_FOR_VIDLE_IRS_SPI_STATUSR(base) \ 158 WAIT_FOR_IDLE(base, irs_spi_statusr, IRS_SPI_STATUSR) 159 160 #define WAIT_FOR_IDLE_IWB_WENABLE_STATUSR(base) \ 161 WAIT_FOR_IDLE(base, iwb_wenable_statusr, IWB_WENABLE_STATUSR) 162 #define WAIT_FOR_IDLE_IWB_WDOMAIN_STATUSR(base) \ 163 WAIT_FOR_IDLE(base, iwb_wdomain_statusr, IWB_WDOMAIN_STATUSR) 164 #define WAIT_FOR_IDLE_IWB_CR0(base) \ 165 WAIT_FOR_IDLE(base, iwb_cr0, IWB_CR0) 166 167 #define WIRE_PROP_DESC(_id, _domain, _tm) \ 168 { \ 169 .id = (_id), \ 170 .domain = (_domain), \ 171 .tm = (_tm), \ 172 } 173 174 struct gicv5_wire_props { 175 /* continuous wire ID as seen by the attached component */ 176 uint32_t id; 177 /* use the INTDMN_XYZ macros */ 178 uint8_t domain:2; 179 /* use the TM_XYZ (eg. TM_EDGE) macros */ 180 uint8_t tm:1; 181 }; 182 183 /* to describe every IRS in the system */ 184 struct gicv5_irs { 185 /* mapped device nGnRnE by the platform*/ 186 uintptr_t el3_config_frame; 187 struct gicv5_wire_props *spis; 188 uint32_t num_spis; 189 }; 190 191 /* 192 * to describe every IWB in the system where EL3 is the MPPAS. IWBs that have 193 * another world as an MPPAS need not be included 194 */ 195 struct gicv5_iwb { 196 /* mapped device nGnRnE by the platform*/ 197 uintptr_t config_frame; 198 struct gicv5_wire_props *wires; 199 uint32_t num_wires; 200 }; 201 202 struct gicv5_driver_data { 203 struct gicv5_irs *irss; 204 struct gicv5_iwb *iwbs; 205 uint32_t num_irss; 206 uint32_t num_iwbs; 207 }; 208 209 extern const struct gicv5_driver_data plat_gicv5_driver_data; 210 211 void gicv5_driver_init(); 212 uint8_t gicv5_get_pending_interrupt_type(void); 213 bool gicv5_has_interrupt_type(unsigned int type); 214 void gicv5_enable_ppis(); 215 #endif /* __ASSEMBLER__ */ 216 #endif /* GICV5_H */ 217