1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 7 * Authors: Sanjay Lal <sanjayl@kymasys.com> 8 * 9 * Copyright (C) 2016 Imagination Technologies 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qemu/log.h" 14 #include "qapi/error.h" 15 #include "hw/hw.h" 16 #include "hw/sysbus.h" 17 #include "exec/memory.h" 18 #include "sysemu/sysemu.h" 19 #include "sysemu/kvm.h" 20 #include "kvm_mips.h" 21 #include "hw/intc/mips_gic.h" 22 23 static void mips_gic_set_vp_irq(MIPSGICState *gic, int vp, int pin, int level) 24 { 25 int ored_level = level; 26 int i; 27 28 /* ORing pending registers sharing same pin */ 29 if (!ored_level) { 30 for (i = 0; i < gic->num_irq; i++) { 31 if ((gic->irq_state[i].map_pin & GIC_MAP_MSK) == pin && 32 gic->irq_state[i].map_vp == vp && 33 gic->irq_state[i].enabled) { 34 ored_level |= gic->irq_state[i].pending; 35 } 36 if (ored_level) { 37 /* no need to iterate all interrupts */ 38 break; 39 } 40 } 41 if (((gic->vps[vp].compare_map & GIC_MAP_MSK) == pin) && 42 (gic->vps[vp].mask & GIC_VP_MASK_CMP_MSK)) { 43 /* ORing with local pending register (count/compare) */ 44 ored_level |= (gic->vps[vp].pend & GIC_VP_MASK_CMP_MSK) >> 45 GIC_VP_MASK_CMP_SHF; 46 } 47 } 48 if (kvm_enabled()) { 49 kvm_mips_set_ipi_interrupt(mips_env_get_cpu(gic->vps[vp].env), 50 pin + GIC_CPU_PIN_OFFSET, 51 ored_level); 52 } else { 53 qemu_set_irq(gic->vps[vp].env->irq[pin + GIC_CPU_PIN_OFFSET], 54 ored_level); 55 } 56 } 57 58 static void gic_set_irq(void *opaque, int n_IRQ, int level) 59 { 60 MIPSGICState *gic = (MIPSGICState *) opaque; 61 int vp = gic->irq_state[n_IRQ].map_vp; 62 int pin = gic->irq_state[n_IRQ].map_pin & GIC_MAP_MSK; 63 64 gic->irq_state[n_IRQ].pending = (uint8_t) level; 65 if (!gic->irq_state[n_IRQ].enabled) { 66 /* GIC interrupt source disabled */ 67 return; 68 } 69 if (vp < 0 || vp >= gic->num_vps) { 70 return; 71 } 72 mips_gic_set_vp_irq(gic, vp, pin, level); 73 } 74 75 #define OFFSET_CHECK(c) \ 76 do { \ 77 if (!(c)) { \ 78 goto bad_offset; \ 79 } \ 80 } while (0) 81 82 /* GIC Read VP Local/Other Registers */ 83 static uint64_t gic_read_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr, 84 unsigned size) 85 { 86 switch (addr) { 87 case GIC_VP_CTL_OFS: 88 return gic->vps[vp_index].ctl; 89 case GIC_VP_PEND_OFS: 90 mips_gictimer_get_sh_count(gic->gic_timer); 91 return gic->vps[vp_index].pend; 92 case GIC_VP_MASK_OFS: 93 return gic->vps[vp_index].mask; 94 case GIC_VP_COMPARE_MAP_OFS: 95 return gic->vps[vp_index].compare_map; 96 case GIC_VP_OTHER_ADDR_OFS: 97 return gic->vps[vp_index].other_addr; 98 case GIC_VP_IDENT_OFS: 99 return vp_index; 100 case GIC_VP_COMPARE_LO_OFS: 101 return mips_gictimer_get_vp_compare(gic->gic_timer, vp_index); 102 case GIC_VP_COMPARE_HI_OFS: 103 return 0; 104 default: 105 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset LOCAL/OTHER 0x%" 106 PRIx64 "\n", size, addr); 107 break; 108 } 109 return 0; 110 } 111 112 static uint64_t gic_read(void *opaque, hwaddr addr, unsigned size) 113 { 114 MIPSGICState *gic = (MIPSGICState *) opaque; 115 uint32_t vp_index = current_cpu->cpu_index; 116 uint64_t ret = 0; 117 int i, base, irq_src; 118 uint32_t other_index; 119 120 switch (addr) { 121 case GIC_SH_CONFIG_OFS: 122 ret = gic->sh_config | (mips_gictimer_get_countstop(gic->gic_timer) << 123 GIC_SH_CONFIG_COUNTSTOP_SHF); 124 break; 125 case GIC_SH_COUNTERLO_OFS: 126 ret = mips_gictimer_get_sh_count(gic->gic_timer); 127 break; 128 case GIC_SH_COUNTERHI_OFS: 129 ret = 0; 130 break; 131 case GIC_SH_PEND_OFS ... GIC_SH_PEND_LAST_OFS: 132 /* each bit represents pending status for an interrupt pin */ 133 base = (addr - GIC_SH_PEND_OFS) * 8; 134 OFFSET_CHECK((base + size * 8) <= gic->num_irq); 135 for (i = 0; i < size * 8; i++) { 136 ret |= (uint64_t) (gic->irq_state[base + i].pending) << i; 137 } 138 break; 139 case GIC_SH_MASK_OFS ... GIC_SH_MASK_LAST_OFS: 140 /* each bit represents status for an interrupt pin */ 141 base = (addr - GIC_SH_MASK_OFS) * 8; 142 OFFSET_CHECK((base + size * 8) <= gic->num_irq); 143 for (i = 0; i < size * 8; i++) { 144 ret |= (uint64_t) (gic->irq_state[base + i].enabled) << i; 145 } 146 break; 147 case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS: 148 /* 32 bits per a pin */ 149 irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4; 150 OFFSET_CHECK(irq_src < gic->num_irq); 151 ret = gic->irq_state[irq_src].map_pin; 152 break; 153 case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS: 154 /* up to 32 bytes per a pin */ 155 irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32; 156 OFFSET_CHECK(irq_src < gic->num_irq); 157 if ((gic->irq_state[irq_src].map_vp) >= 0) { 158 ret = (uint64_t) 1 << (gic->irq_state[irq_src].map_vp); 159 } else { 160 ret = 0; 161 } 162 break; 163 /* VP-Local Register */ 164 case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP): 165 ret = gic_read_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, size); 166 break; 167 /* VP-Other Register */ 168 case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP): 169 other_index = gic->vps[vp_index].other_addr; 170 ret = gic_read_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, size); 171 break; 172 /* User-Mode Visible section */ 173 case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO: 174 ret = mips_gictimer_get_sh_count(gic->gic_timer); 175 break; 176 case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI: 177 ret = 0; 178 break; 179 default: 180 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GIC offset 0x%" PRIx64 "\n", 181 size, addr); 182 break; 183 } 184 return ret; 185 bad_offset: 186 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); 187 return 0; 188 } 189 190 static void gic_timer_expire_cb(void *opaque, uint32_t vp_index) 191 { 192 MIPSGICState *gic = opaque; 193 194 gic->vps[vp_index].pend |= (1 << GIC_LOCAL_INT_COMPARE); 195 if (gic->vps[vp_index].pend & 196 (gic->vps[vp_index].mask & GIC_VP_MASK_CMP_MSK)) { 197 if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) { 198 /* it is safe to set the irq high regardless of other GIC IRQs */ 199 uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK); 200 qemu_irq_raise(gic->vps[vp_index].env->irq 201 [pin + GIC_CPU_PIN_OFFSET]); 202 } 203 } 204 } 205 206 static void gic_timer_store_vp_compare(MIPSGICState *gic, uint32_t vp_index, 207 uint64_t compare) 208 { 209 gic->vps[vp_index].pend &= ~(1 << GIC_LOCAL_INT_COMPARE); 210 if (gic->vps[vp_index].compare_map & GIC_MAP_TO_PIN_MSK) { 211 uint32_t pin = (gic->vps[vp_index].compare_map & GIC_MAP_MSK); 212 mips_gic_set_vp_irq(gic, vp_index, pin, 0); 213 } 214 mips_gictimer_store_vp_compare(gic->gic_timer, vp_index, compare); 215 } 216 217 /* GIC Write VP Local/Other Registers */ 218 static void gic_write_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr, 219 uint64_t data, unsigned size) 220 { 221 switch (addr) { 222 case GIC_VP_CTL_OFS: 223 /* EIC isn't supported */ 224 break; 225 case GIC_VP_RMASK_OFS: 226 gic->vps[vp_index].mask &= ~(data & GIC_VP_SET_RESET_MSK) & 227 GIC_VP_SET_RESET_MSK; 228 break; 229 case GIC_VP_SMASK_OFS: 230 gic->vps[vp_index].mask |= data & GIC_VP_SET_RESET_MSK; 231 break; 232 case GIC_VP_COMPARE_MAP_OFS: 233 /* EIC isn't supported */ 234 OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX); 235 gic->vps[vp_index].compare_map = data & GIC_MAP_TO_PIN_REG_MSK; 236 break; 237 case GIC_VP_OTHER_ADDR_OFS: 238 OFFSET_CHECK(data < gic->num_vps); 239 gic->vps[vp_index].other_addr = data; 240 break; 241 case GIC_VP_COMPARE_LO_OFS: 242 gic_timer_store_vp_compare(gic, vp_index, data); 243 break; 244 default: 245 qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset LOCAL/OTHER " 246 "0x%" PRIx64" 0x%08" PRIx64 "\n", size, addr, data); 247 break; 248 } 249 return; 250 bad_offset: 251 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); 252 return; 253 } 254 255 static void gic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) 256 { 257 int intr; 258 MIPSGICState *gic = (MIPSGICState *) opaque; 259 uint32_t vp_index = current_cpu->cpu_index; 260 int i, base, irq_src; 261 uint32_t other_index; 262 263 switch (addr) { 264 case GIC_SH_CONFIG_OFS: 265 { 266 uint32_t pre_cntstop = mips_gictimer_get_countstop(gic->gic_timer); 267 uint32_t new_cntstop = (data & GIC_SH_CONFIG_COUNTSTOP_MSK) >> 268 GIC_SH_CONFIG_COUNTSTOP_SHF; 269 if (pre_cntstop != new_cntstop) { 270 if (new_cntstop == 1) { 271 mips_gictimer_stop_count(gic->gic_timer); 272 } else { 273 mips_gictimer_start_count(gic->gic_timer); 274 } 275 } 276 } 277 break; 278 case GIC_SH_COUNTERLO_OFS: 279 if (mips_gictimer_get_countstop(gic->gic_timer)) { 280 mips_gictimer_store_sh_count(gic->gic_timer, data); 281 } 282 break; 283 case GIC_SH_RMASK_OFS ... GIC_SH_RMASK_LAST_OFS: 284 /* up to 64 bits per a pin */ 285 base = (addr - GIC_SH_RMASK_OFS) * 8; 286 OFFSET_CHECK((base + size * 8) <= gic->num_irq); 287 for (i = 0; i < size * 8; i++) { 288 gic->irq_state[base + i].enabled &= !((data >> i) & 1); 289 } 290 break; 291 case GIC_SH_WEDGE_OFS: 292 /* Figure out which VP/HW Interrupt this maps to */ 293 intr = data & ~GIC_SH_WEDGE_RW_MSK; 294 /* Mask/Enabled Checks */ 295 OFFSET_CHECK(intr < gic->num_irq); 296 if (data & GIC_SH_WEDGE_RW_MSK) { 297 gic_set_irq(gic, intr, 1); 298 } else { 299 gic_set_irq(gic, intr, 0); 300 } 301 break; 302 case GIC_SH_SMASK_OFS ... GIC_SH_SMASK_LAST_OFS: 303 /* up to 64 bits per a pin */ 304 base = (addr - GIC_SH_SMASK_OFS) * 8; 305 OFFSET_CHECK((base + size * 8) <= gic->num_irq); 306 for (i = 0; i < size * 8; i++) { 307 gic->irq_state[base + i].enabled |= (data >> i) & 1; 308 } 309 break; 310 case GIC_SH_MAP0_PIN_OFS ... GIC_SH_MAP255_PIN_OFS: 311 /* 32 bits per a pin */ 312 irq_src = (addr - GIC_SH_MAP0_PIN_OFS) / 4; 313 OFFSET_CHECK(irq_src < gic->num_irq); 314 /* EIC isn't supported */ 315 OFFSET_CHECK((data & GIC_MAP_MSK) <= GIC_CPU_INT_MAX); 316 gic->irq_state[irq_src].map_pin = data & GIC_MAP_TO_PIN_REG_MSK; 317 break; 318 case GIC_SH_MAP0_VP_OFS ... GIC_SH_MAP255_VP_LAST_OFS: 319 /* up to 32 bytes per a pin */ 320 irq_src = (addr - GIC_SH_MAP0_VP_OFS) / 32; 321 OFFSET_CHECK(irq_src < gic->num_irq); 322 data = data ? ctz64(data) : -1; 323 OFFSET_CHECK(data < gic->num_vps); 324 gic->irq_state[irq_src].map_vp = data; 325 break; 326 case VP_LOCAL_SECTION_OFS ... (VP_LOCAL_SECTION_OFS + GIC_VL_BRK_GROUP): 327 gic_write_vp(gic, vp_index, addr - VP_LOCAL_SECTION_OFS, data, size); 328 break; 329 case VP_OTHER_SECTION_OFS ... (VP_OTHER_SECTION_OFS + GIC_VL_BRK_GROUP): 330 other_index = gic->vps[vp_index].other_addr; 331 gic_write_vp(gic, other_index, addr - VP_OTHER_SECTION_OFS, data, size); 332 break; 333 case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERLO: 334 case USM_VISIBLE_SECTION_OFS + GIC_USER_MODE_COUNTERHI: 335 /* do nothing. Read-only section */ 336 break; 337 default: 338 qemu_log_mask(LOG_UNIMP, "Write %d bytes at GIC offset 0x%" PRIx64 339 " 0x%08" PRIx64 "\n", size, addr, data); 340 break; 341 } 342 return; 343 bad_offset: 344 qemu_log_mask(LOG_GUEST_ERROR, "Wrong GIC offset at 0x%" PRIx64 "\n", addr); 345 } 346 347 static void gic_reset(void *opaque) 348 { 349 int i; 350 MIPSGICState *gic = (MIPSGICState *) opaque; 351 int numintrs = (gic->num_irq / 8) - 1; 352 353 gic->sh_config = /* COUNTSTOP = 0 it is accessible via MIPSGICTimer*/ 354 /* CounterHi not implemented */ 355 (0 << GIC_SH_CONFIG_COUNTBITS_SHF) | 356 (numintrs << GIC_SH_CONFIG_NUMINTRS_SHF) | 357 (gic->num_vps << GIC_SH_CONFIG_PVPS_SHF); 358 for (i = 0; i < gic->num_vps; i++) { 359 gic->vps[i].ctl = 0x0; 360 gic->vps[i].pend = 0x0; 361 /* PERFCNT, TIMER and WD not implemented */ 362 gic->vps[i].mask = 0x32; 363 gic->vps[i].compare_map = GIC_MAP_TO_PIN_MSK; 364 mips_gictimer_store_vp_compare(gic->gic_timer, i, 0xffffffff); 365 gic->vps[i].other_addr = 0x0; 366 } 367 for (i = 0; i < gic->num_irq; i++) { 368 gic->irq_state[i].enabled = 0; 369 gic->irq_state[i].pending = 0; 370 gic->irq_state[i].map_pin = GIC_MAP_TO_PIN_MSK; 371 gic->irq_state[i].map_vp = -1; 372 } 373 mips_gictimer_store_sh_count(gic->gic_timer, 0); 374 /* COUNTSTOP = 0 */ 375 mips_gictimer_start_count(gic->gic_timer); 376 } 377 378 static const MemoryRegionOps gic_ops = { 379 .read = gic_read, 380 .write = gic_write, 381 .endianness = DEVICE_NATIVE_ENDIAN, 382 .impl = { 383 .max_access_size = 8, 384 }, 385 }; 386 387 static void mips_gic_init(Object *obj) 388 { 389 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 390 MIPSGICState *s = MIPS_GIC(obj); 391 392 memory_region_init_io(&s->mr, OBJECT(s), &gic_ops, s, 393 "mips-gic", GIC_ADDRSPACE_SZ); 394 sysbus_init_mmio(sbd, &s->mr); 395 qemu_register_reset(gic_reset, s); 396 } 397 398 static void mips_gic_realize(DeviceState *dev, Error **errp) 399 { 400 MIPSGICState *s = MIPS_GIC(dev); 401 CPUState *cs = first_cpu; 402 int i; 403 404 if (s->num_vps > GIC_MAX_VPS) { 405 error_setg(errp, "Exceeded maximum CPUs %d", s->num_vps); 406 return; 407 } 408 if ((s->num_irq > GIC_MAX_INTRS) || (s->num_irq % 8) || (s->num_irq <= 0)) { 409 error_setg(errp, "GIC supports up to %d external interrupts in " 410 "multiples of 8 : %d", GIC_MAX_INTRS, s->num_irq); 411 return; 412 } 413 s->vps = g_new(MIPSGICVPState, s->num_vps); 414 s->irq_state = g_new(MIPSGICIRQState, s->num_irq); 415 /* Register the env for all VPs with the GIC */ 416 for (i = 0; i < s->num_vps; i++) { 417 if (cs != NULL) { 418 s->vps[i].env = cs->env_ptr; 419 cs = CPU_NEXT(cs); 420 } else { 421 error_setg(errp, 422 "Unable to initialize GIC, CPUState for CPU#%d not valid.", i); 423 return; 424 } 425 } 426 s->gic_timer = mips_gictimer_init(s, s->num_vps, gic_timer_expire_cb); 427 qdev_init_gpio_in(dev, gic_set_irq, s->num_irq); 428 for (i = 0; i < s->num_irq; i++) { 429 s->irq_state[i].irq = qdev_get_gpio_in(dev, i); 430 } 431 } 432 433 static Property mips_gic_properties[] = { 434 DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1), 435 DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256), 436 DEFINE_PROP_END_OF_LIST(), 437 }; 438 439 static void mips_gic_class_init(ObjectClass *klass, void *data) 440 { 441 DeviceClass *dc = DEVICE_CLASS(klass); 442 443 dc->props = mips_gic_properties; 444 dc->realize = mips_gic_realize; 445 } 446 447 static const TypeInfo mips_gic_info = { 448 .name = TYPE_MIPS_GIC, 449 .parent = TYPE_SYS_BUS_DEVICE, 450 .instance_size = sizeof(MIPSGICState), 451 .instance_init = mips_gic_init, 452 .class_init = mips_gic_class_init, 453 }; 454 455 static void mips_gic_register_types(void) 456 { 457 type_register_static(&mips_gic_info); 458 } 459 460 type_init(mips_gic_register_types) 461