1 /* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <assert.h> 32 #include <gic_common.h> 33 #include <mmio.h> 34 35 /******************************************************************************* 36 * GIC Distributor interface accessors for reading entire registers 37 ******************************************************************************/ 38 /* 39 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt 40 * `id`, 32 interrupt ids at a time. 41 */ 42 unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id) 43 { 44 unsigned n = id >> IGROUPR_SHIFT; 45 return mmio_read_32(base + GICD_IGROUPR + (n << 2)); 46 } 47 48 /* 49 * Accessor to read the GIC Distributor ISENABLER corresponding to the 50 * interrupt `id`, 32 interrupt ids at a time. 51 */ 52 unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id) 53 { 54 unsigned n = id >> ISENABLER_SHIFT; 55 return mmio_read_32(base + GICD_ISENABLER + (n << 2)); 56 } 57 58 /* 59 * Accessor to read the GIC Distributor ICENABLER corresponding to the 60 * interrupt `id`, 32 interrupt IDs at a time. 61 */ 62 unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id) 63 { 64 unsigned n = id >> ICENABLER_SHIFT; 65 return mmio_read_32(base + GICD_ICENABLER + (n << 2)); 66 } 67 68 /* 69 * Accessor to read the GIC Distributor ISPENDR corresponding to the 70 * interrupt `id`, 32 interrupt IDs at a time. 71 */ 72 unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id) 73 { 74 unsigned n = id >> ISPENDR_SHIFT; 75 return mmio_read_32(base + GICD_ISPENDR + (n << 2)); 76 } 77 78 /* 79 * Accessor to read the GIC Distributor ICPENDR corresponding to the 80 * interrupt `id`, 32 interrupt IDs at a time. 81 */ 82 unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id) 83 { 84 unsigned n = id >> ICPENDR_SHIFT; 85 return mmio_read_32(base + GICD_ICPENDR + (n << 2)); 86 } 87 88 /* 89 * Accessor to read the GIC Distributor ISACTIVER corresponding to the 90 * interrupt `id`, 32 interrupt IDs at a time. 91 */ 92 unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id) 93 { 94 unsigned n = id >> ISACTIVER_SHIFT; 95 return mmio_read_32(base + GICD_ISACTIVER + (n << 2)); 96 } 97 98 /* 99 * Accessor to read the GIC Distributor ICACTIVER corresponding to the 100 * interrupt `id`, 32 interrupt IDs at a time. 101 */ 102 unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id) 103 { 104 unsigned n = id >> ICACTIVER_SHIFT; 105 return mmio_read_32(base + GICD_ICACTIVER + (n << 2)); 106 } 107 108 /* 109 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the 110 * interrupt `id`, 4 interrupt IDs at a time. 111 */ 112 unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id) 113 { 114 unsigned n = id >> IPRIORITYR_SHIFT; 115 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2)); 116 } 117 118 /* 119 * Accessor to read the GIC Distributor ICGFR corresponding to the 120 * interrupt `id`, 16 interrupt IDs at a time. 121 */ 122 unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id) 123 { 124 unsigned n = id >> ICFGR_SHIFT; 125 return mmio_read_32(base + GICD_ICFGR + (n << 2)); 126 } 127 128 /* 129 * Accessor to read the GIC Distributor NSACR corresponding to the 130 * interrupt `id`, 16 interrupt IDs at a time. 131 */ 132 unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id) 133 { 134 unsigned n = id >> NSACR_SHIFT; 135 return mmio_read_32(base + GICD_NSACR + (n << 2)); 136 } 137 138 /******************************************************************************* 139 * GIC Distributor interface accessors for writing entire registers 140 ******************************************************************************/ 141 /* 142 * Accessor to write the GIC Distributor IGROUPR corresponding to the 143 * interrupt `id`, 32 interrupt IDs at a time. 144 */ 145 void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val) 146 { 147 unsigned n = id >> IGROUPR_SHIFT; 148 mmio_write_32(base + GICD_IGROUPR + (n << 2), val); 149 } 150 151 /* 152 * Accessor to write the GIC Distributor ISENABLER corresponding to the 153 * interrupt `id`, 32 interrupt IDs at a time. 154 */ 155 void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val) 156 { 157 unsigned n = id >> ISENABLER_SHIFT; 158 mmio_write_32(base + GICD_ISENABLER + (n << 2), val); 159 } 160 161 /* 162 * Accessor to write the GIC Distributor ICENABLER corresponding to the 163 * interrupt `id`, 32 interrupt IDs at a time. 164 */ 165 void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val) 166 { 167 unsigned n = id >> ICENABLER_SHIFT; 168 mmio_write_32(base + GICD_ICENABLER + (n << 2), val); 169 } 170 171 /* 172 * Accessor to write the GIC Distributor ISPENDR corresponding to the 173 * interrupt `id`, 32 interrupt IDs at a time. 174 */ 175 void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val) 176 { 177 unsigned n = id >> ISPENDR_SHIFT; 178 mmio_write_32(base + GICD_ISPENDR + (n << 2), val); 179 } 180 181 /* 182 * Accessor to write the GIC Distributor ICPENDR corresponding to the 183 * interrupt `id`, 32 interrupt IDs at a time. 184 */ 185 void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val) 186 { 187 unsigned n = id >> ICPENDR_SHIFT; 188 mmio_write_32(base + GICD_ICPENDR + (n << 2), val); 189 } 190 191 /* 192 * Accessor to write the GIC Distributor ISACTIVER corresponding to the 193 * interrupt `id`, 32 interrupt IDs at a time. 194 */ 195 void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val) 196 { 197 unsigned n = id >> ISACTIVER_SHIFT; 198 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val); 199 } 200 201 /* 202 * Accessor to write the GIC Distributor ICACTIVER corresponding to the 203 * interrupt `id`, 32 interrupt IDs at a time. 204 */ 205 void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val) 206 { 207 unsigned n = id >> ICACTIVER_SHIFT; 208 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val); 209 } 210 211 /* 212 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the 213 * interrupt `id`, 4 interrupt IDs at a time. 214 */ 215 void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 216 { 217 unsigned n = id >> IPRIORITYR_SHIFT; 218 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val); 219 } 220 221 /* 222 * Accessor to write the GIC Distributor ICFGR corresponding to the 223 * interrupt `id`, 16 interrupt IDs at a time. 224 */ 225 void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val) 226 { 227 unsigned n = id >> ICFGR_SHIFT; 228 mmio_write_32(base + GICD_ICFGR + (n << 2), val); 229 } 230 231 /* 232 * Accessor to write the GIC Distributor NSACR corresponding to the 233 * interrupt `id`, 16 interrupt IDs at a time. 234 */ 235 void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) 236 { 237 unsigned n = id >> NSACR_SHIFT; 238 mmio_write_32(base + GICD_NSACR + (n << 2), val); 239 } 240 241 /******************************************************************************* 242 * GIC Distributor interface accessors for individual interrupt manipulation 243 ******************************************************************************/ 244 unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) 245 { 246 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 247 unsigned int reg_val = gicd_read_igroupr(base, id); 248 249 return (reg_val >> bit_num) & 0x1; 250 } 251 252 void gicd_set_igroupr(uintptr_t base, unsigned int id) 253 { 254 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 255 unsigned int reg_val = gicd_read_igroupr(base, id); 256 257 gicd_write_igroupr(base, id, reg_val | (1 << bit_num)); 258 } 259 260 void gicd_clr_igroupr(uintptr_t base, unsigned int id) 261 { 262 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 263 unsigned int reg_val = gicd_read_igroupr(base, id); 264 265 gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num)); 266 } 267 268 void gicd_set_isenabler(uintptr_t base, unsigned int id) 269 { 270 unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); 271 272 gicd_write_isenabler(base, id, (1 << bit_num)); 273 } 274 275 void gicd_set_icenabler(uintptr_t base, unsigned int id) 276 { 277 unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); 278 279 gicd_write_icenabler(base, id, (1 << bit_num)); 280 } 281 282 void gicd_set_ispendr(uintptr_t base, unsigned int id) 283 { 284 unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); 285 286 gicd_write_ispendr(base, id, (1 << bit_num)); 287 } 288 289 void gicd_set_icpendr(uintptr_t base, unsigned int id) 290 { 291 unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); 292 293 gicd_write_icpendr(base, id, (1 << bit_num)); 294 } 295 296 void gicd_set_isactiver(uintptr_t base, unsigned int id) 297 { 298 unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); 299 300 gicd_write_isactiver(base, id, (1 << bit_num)); 301 } 302 303 void gicd_set_icactiver(uintptr_t base, unsigned int id) 304 { 305 unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1); 306 307 gicd_write_icactiver(base, id, (1 << bit_num)); 308 } 309