1 /* 2 * OpenPIC emulation 3 * 4 * Copyright (c) 2004 Jocelyn Mayer 5 * 2011 Alexander Graf 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 /* 26 * 27 * Based on OpenPic implementations: 28 * - Motorola MPC8245 & MPC8540 user manuals. 29 * - Motorola Harrier programmer manual 30 * 31 */ 32 33 #include "qemu/osdep.h" 34 #include "hw/irq.h" 35 #include "hw/ppc/mac.h" 36 #include "hw/pci/pci.h" 37 #include "hw/ppc/openpic.h" 38 #include "hw/ppc/ppc_e500.h" 39 #include "hw/qdev-properties.h" 40 #include "hw/sysbus.h" 41 #include "migration/vmstate.h" 42 #include "hw/pci/msi.h" 43 #include "qapi/error.h" 44 #include "qemu/bitops.h" 45 #include "qapi/qmp/qerror.h" 46 #include "qemu/module.h" 47 #include "qemu/timer.h" 48 #include "qemu/error-report.h" 49 50 //#define DEBUG_OPENPIC 51 52 #ifdef DEBUG_OPENPIC 53 static const int debug_openpic = 1; 54 #else 55 static const int debug_openpic = 0; 56 #endif 57 58 static int get_current_cpu(void); 59 #define DPRINTF(fmt, ...) do { \ 60 if (debug_openpic) { \ 61 info_report("Core%d: " fmt, get_current_cpu(), ## __VA_ARGS__); \ 62 } \ 63 } while (0) 64 65 /* OpenPIC capability flags */ 66 #define OPENPIC_FLAG_IDR_CRIT (1 << 0) 67 #define OPENPIC_FLAG_ILR (2 << 0) 68 69 /* OpenPIC address map */ 70 #define OPENPIC_GLB_REG_START 0x0 71 #define OPENPIC_GLB_REG_SIZE 0x10F0 72 #define OPENPIC_TMR_REG_START 0x10F0 73 #define OPENPIC_TMR_REG_SIZE 0x220 74 #define OPENPIC_MSI_REG_START 0x1600 75 #define OPENPIC_MSI_REG_SIZE 0x200 76 #define OPENPIC_SUMMARY_REG_START 0x3800 77 #define OPENPIC_SUMMARY_REG_SIZE 0x800 78 #define OPENPIC_SRC_REG_START 0x10000 79 #define OPENPIC_SRC_REG_SIZE (OPENPIC_MAX_SRC * 0x20) 80 #define OPENPIC_CPU_REG_START 0x20000 81 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000) 82 83 static FslMpicInfo fsl_mpic_20 = { 84 .max_ext = 12, 85 }; 86 87 static FslMpicInfo fsl_mpic_42 = { 88 .max_ext = 12, 89 }; 90 91 #define FRR_NIRQ_SHIFT 16 92 #define FRR_NCPU_SHIFT 8 93 #define FRR_VID_SHIFT 0 94 95 #define VID_REVISION_1_2 2 96 #define VID_REVISION_1_3 3 97 98 #define VIR_GENERIC 0x00000000 /* Generic Vendor ID */ 99 #define VIR_MPIC2A 0x00004614 /* IBM MPIC-2A */ 100 101 #define GCR_RESET 0x80000000 102 #define GCR_MODE_PASS 0x00000000 103 #define GCR_MODE_MIXED 0x20000000 104 #define GCR_MODE_PROXY 0x60000000 105 106 #define TBCR_CI 0x80000000 /* count inhibit */ 107 #define TCCR_TOG 0x80000000 /* toggles when decrement to zero */ 108 109 #define IDR_EP_SHIFT 31 110 #define IDR_EP_MASK (1U << IDR_EP_SHIFT) 111 #define IDR_CI0_SHIFT 30 112 #define IDR_CI1_SHIFT 29 113 #define IDR_P1_SHIFT 1 114 #define IDR_P0_SHIFT 0 115 116 #define ILR_INTTGT_MASK 0x000000ff 117 #define ILR_INTTGT_INT 0x00 118 #define ILR_INTTGT_CINT 0x01 /* critical */ 119 #define ILR_INTTGT_MCP 0x02 /* machine check */ 120 121 /* The currently supported INTTGT values happen to be the same as QEMU's 122 * openpic output codes, but don't depend on this. The output codes 123 * could change (unlikely, but...) or support could be added for 124 * more INTTGT values. 125 */ 126 static const int inttgt_output[][2] = { 127 { ILR_INTTGT_INT, OPENPIC_OUTPUT_INT }, 128 { ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT }, 129 { ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK }, 130 }; 131 132 static int inttgt_to_output(int inttgt) 133 { 134 int i; 135 136 for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) { 137 if (inttgt_output[i][0] == inttgt) { 138 return inttgt_output[i][1]; 139 } 140 } 141 142 error_report("%s: unsupported inttgt %d", __func__, inttgt); 143 return OPENPIC_OUTPUT_INT; 144 } 145 146 static int output_to_inttgt(int output) 147 { 148 int i; 149 150 for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) { 151 if (inttgt_output[i][1] == output) { 152 return inttgt_output[i][0]; 153 } 154 } 155 156 abort(); 157 } 158 159 #define MSIIR_OFFSET 0x140 160 #define MSIIR_SRS_SHIFT 29 161 #define MSIIR_SRS_MASK (0x7 << MSIIR_SRS_SHIFT) 162 #define MSIIR_IBS_SHIFT 24 163 #define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT) 164 165 static int get_current_cpu(void) 166 { 167 if (!current_cpu) { 168 return -1; 169 } 170 171 return current_cpu->cpu_index; 172 } 173 174 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, 175 int idx); 176 static void openpic_cpu_write_internal(void *opaque, hwaddr addr, 177 uint32_t val, int idx); 178 static void openpic_reset(DeviceState *d); 179 180 /* Convert between openpic clock ticks and nanosecs. In the hardware the clock 181 frequency is driven by board inputs to the PIC which the PIC would then 182 divide by 4 or 8. For now hard code to 25MZ. 183 */ 184 #define OPENPIC_TIMER_FREQ_MHZ 25 185 #define OPENPIC_TIMER_NS_PER_TICK (1000 / OPENPIC_TIMER_FREQ_MHZ) 186 static inline uint64_t ns_to_ticks(uint64_t ns) 187 { 188 return ns / OPENPIC_TIMER_NS_PER_TICK; 189 } 190 static inline uint64_t ticks_to_ns(uint64_t ticks) 191 { 192 return ticks * OPENPIC_TIMER_NS_PER_TICK; 193 } 194 195 static inline void IRQ_setbit(IRQQueue *q, int n_IRQ) 196 { 197 set_bit(n_IRQ, q->queue); 198 } 199 200 static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ) 201 { 202 clear_bit(n_IRQ, q->queue); 203 } 204 205 static void IRQ_check(OpenPICState *opp, IRQQueue *q) 206 { 207 int irq = -1; 208 int next = -1; 209 int priority = -1; 210 211 for (;;) { 212 irq = find_next_bit(q->queue, opp->max_irq, irq + 1); 213 if (irq == opp->max_irq) { 214 break; 215 } 216 217 DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d", 218 irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority); 219 220 if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) { 221 next = irq; 222 priority = IVPR_PRIORITY(opp->src[irq].ivpr); 223 } 224 } 225 226 q->next = next; 227 q->priority = priority; 228 } 229 230 static int IRQ_get_next(OpenPICState *opp, IRQQueue *q) 231 { 232 /* XXX: optimize */ 233 IRQ_check(opp, q); 234 235 return q->next; 236 } 237 238 static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ, 239 bool active, bool was_active) 240 { 241 IRQDest *dst; 242 IRQSource *src; 243 int priority; 244 245 dst = &opp->dst[n_CPU]; 246 src = &opp->src[n_IRQ]; 247 248 DPRINTF("%s: IRQ %d active %d was %d", 249 __func__, n_IRQ, active, was_active); 250 251 if (src->output != OPENPIC_OUTPUT_INT) { 252 DPRINTF("%s: output %d irq %d active %d was %d count %d", 253 __func__, src->output, n_IRQ, active, was_active, 254 dst->outputs_active[src->output]); 255 256 /* On Freescale MPIC, critical interrupts ignore priority, 257 * IACK, EOI, etc. Before MPIC v4.1 they also ignore 258 * masking. 259 */ 260 if (active) { 261 if (!was_active && dst->outputs_active[src->output]++ == 0) { 262 DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d", 263 __func__, src->output, n_CPU, n_IRQ); 264 qemu_irq_raise(dst->irqs[src->output]); 265 } 266 } else { 267 if (was_active && --dst->outputs_active[src->output] == 0) { 268 DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d", 269 __func__, src->output, n_CPU, n_IRQ); 270 qemu_irq_lower(dst->irqs[src->output]); 271 } 272 } 273 274 return; 275 } 276 277 priority = IVPR_PRIORITY(src->ivpr); 278 279 /* Even if the interrupt doesn't have enough priority, 280 * it is still raised, in case ctpr is lowered later. 281 */ 282 if (active) { 283 IRQ_setbit(&dst->raised, n_IRQ); 284 } else { 285 IRQ_resetbit(&dst->raised, n_IRQ); 286 } 287 288 IRQ_check(opp, &dst->raised); 289 290 if (active && priority <= dst->ctpr) { 291 DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d", 292 __func__, n_IRQ, priority, dst->ctpr, n_CPU); 293 active = 0; 294 } 295 296 if (active) { 297 if (IRQ_get_next(opp, &dst->servicing) >= 0 && 298 priority <= dst->servicing.priority) { 299 DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d", 300 __func__, n_IRQ, dst->servicing.next, n_CPU); 301 } else { 302 DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d", 303 __func__, n_CPU, n_IRQ, dst->raised.next); 304 qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); 305 } 306 } else { 307 IRQ_get_next(opp, &dst->servicing); 308 if (dst->raised.priority > dst->ctpr && 309 dst->raised.priority > dst->servicing.priority) { 310 DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d", 311 __func__, n_IRQ, dst->raised.next, dst->raised.priority, 312 dst->ctpr, dst->servicing.priority, n_CPU); 313 /* IRQ line stays asserted */ 314 } else { 315 DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d", 316 __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU); 317 qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); 318 } 319 } 320 } 321 322 /* update pic state because registers for n_IRQ have changed value */ 323 static void openpic_update_irq(OpenPICState *opp, int n_IRQ) 324 { 325 IRQSource *src; 326 bool active, was_active; 327 int i; 328 329 src = &opp->src[n_IRQ]; 330 active = src->pending; 331 332 if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) { 333 /* Interrupt source is disabled */ 334 DPRINTF("%s: IRQ %d is disabled", __func__, n_IRQ); 335 active = false; 336 } 337 338 was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK); 339 340 /* 341 * We don't have a similar check for already-active because 342 * ctpr may have changed and we need to withdraw the interrupt. 343 */ 344 if (!active && !was_active) { 345 DPRINTF("%s: IRQ %d is already inactive", __func__, n_IRQ); 346 return; 347 } 348 349 if (active) { 350 src->ivpr |= IVPR_ACTIVITY_MASK; 351 } else { 352 src->ivpr &= ~IVPR_ACTIVITY_MASK; 353 } 354 355 if (src->destmask == 0) { 356 /* No target */ 357 DPRINTF("%s: IRQ %d has no target", __func__, n_IRQ); 358 return; 359 } 360 361 if (src->destmask == (1 << src->last_cpu)) { 362 /* Only one CPU is allowed to receive this IRQ */ 363 IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active); 364 } else if (!(src->ivpr & IVPR_MODE_MASK)) { 365 /* Directed delivery mode */ 366 for (i = 0; i < opp->nb_cpus; i++) { 367 if (src->destmask & (1 << i)) { 368 IRQ_local_pipe(opp, i, n_IRQ, active, was_active); 369 } 370 } 371 } else { 372 /* Distributed delivery mode */ 373 for (i = src->last_cpu + 1; i != src->last_cpu; i++) { 374 if (i == opp->nb_cpus) { 375 i = 0; 376 } 377 if (src->destmask & (1 << i)) { 378 IRQ_local_pipe(opp, i, n_IRQ, active, was_active); 379 src->last_cpu = i; 380 break; 381 } 382 } 383 } 384 } 385 386 static void openpic_set_irq(void *opaque, int n_IRQ, int level) 387 { 388 OpenPICState *opp = opaque; 389 IRQSource *src; 390 391 if (n_IRQ >= OPENPIC_MAX_IRQ) { 392 error_report("%s: IRQ %d out of range", __func__, n_IRQ); 393 abort(); 394 } 395 396 src = &opp->src[n_IRQ]; 397 DPRINTF("openpic: set irq %d = %d ivpr=0x%08x", 398 n_IRQ, level, src->ivpr); 399 if (src->level) { 400 /* level-sensitive irq */ 401 src->pending = level; 402 openpic_update_irq(opp, n_IRQ); 403 } else { 404 /* edge-sensitive irq */ 405 if (level) { 406 src->pending = 1; 407 openpic_update_irq(opp, n_IRQ); 408 } 409 410 if (src->output != OPENPIC_OUTPUT_INT) { 411 /* Edge-triggered interrupts shouldn't be used 412 * with non-INT delivery, but just in case, 413 * try to make it do something sane rather than 414 * cause an interrupt storm. This is close to 415 * what you'd probably see happen in real hardware. 416 */ 417 src->pending = 0; 418 openpic_update_irq(opp, n_IRQ); 419 } 420 } 421 } 422 423 static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ) 424 { 425 return opp->src[n_IRQ].idr; 426 } 427 428 static inline uint32_t read_IRQreg_ilr(OpenPICState *opp, int n_IRQ) 429 { 430 if (opp->flags & OPENPIC_FLAG_ILR) { 431 return output_to_inttgt(opp->src[n_IRQ].output); 432 } 433 434 return 0xffffffff; 435 } 436 437 static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ) 438 { 439 return opp->src[n_IRQ].ivpr; 440 } 441 442 static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val) 443 { 444 IRQSource *src = &opp->src[n_IRQ]; 445 uint32_t normal_mask = (1UL << opp->nb_cpus) - 1; 446 uint32_t crit_mask = 0; 447 uint32_t mask = normal_mask; 448 int crit_shift = IDR_EP_SHIFT - opp->nb_cpus; 449 int i; 450 451 if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { 452 crit_mask = mask << crit_shift; 453 mask |= crit_mask | IDR_EP; 454 } 455 456 src->idr = val & mask; 457 DPRINTF("Set IDR %d to 0x%08x", n_IRQ, src->idr); 458 459 if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { 460 if (src->idr & crit_mask) { 461 if (src->idr & normal_mask) { 462 DPRINTF("%s: IRQ configured for multiple output types, using " 463 "critical", __func__); 464 } 465 466 src->output = OPENPIC_OUTPUT_CINT; 467 src->nomask = true; 468 src->destmask = 0; 469 470 for (i = 0; i < opp->nb_cpus; i++) { 471 int n_ci = IDR_CI0_SHIFT - i; 472 473 if (src->idr & (1UL << n_ci)) { 474 src->destmask |= 1UL << i; 475 } 476 } 477 } else { 478 src->output = OPENPIC_OUTPUT_INT; 479 src->nomask = false; 480 src->destmask = src->idr & normal_mask; 481 } 482 } else { 483 src->destmask = src->idr; 484 } 485 } 486 487 static inline void write_IRQreg_ilr(OpenPICState *opp, int n_IRQ, uint32_t val) 488 { 489 if (opp->flags & OPENPIC_FLAG_ILR) { 490 IRQSource *src = &opp->src[n_IRQ]; 491 492 src->output = inttgt_to_output(val & ILR_INTTGT_MASK); 493 DPRINTF("Set ILR %d to 0x%08x, output %d", n_IRQ, src->idr, 494 src->output); 495 496 /* TODO: on MPIC v4.0 only, set nomask for non-INT */ 497 } 498 } 499 500 static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val) 501 { 502 uint32_t mask; 503 504 /* NOTE when implementing newer FSL MPIC models: starting with v4.0, 505 * the polarity bit is read-only on internal interrupts. 506 */ 507 mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK | 508 IVPR_POLARITY_MASK | opp->vector_mask; 509 510 /* ACTIVITY bit is read-only */ 511 opp->src[n_IRQ].ivpr = 512 (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask); 513 514 /* For FSL internal interrupts, The sense bit is reserved and zero, 515 * and the interrupt is always level-triggered. Timers and IPIs 516 * have no sense or polarity bits, and are edge-triggered. 517 */ 518 switch (opp->src[n_IRQ].type) { 519 case IRQ_TYPE_NORMAL: 520 opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK); 521 break; 522 523 case IRQ_TYPE_FSLINT: 524 opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK; 525 break; 526 527 case IRQ_TYPE_FSLSPECIAL: 528 opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK); 529 break; 530 } 531 532 openpic_update_irq(opp, n_IRQ); 533 DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x", n_IRQ, val, 534 opp->src[n_IRQ].ivpr); 535 } 536 537 static void openpic_gcr_write(OpenPICState *opp, uint64_t val) 538 { 539 bool mpic_proxy = false; 540 541 if (val & GCR_RESET) { 542 openpic_reset(DEVICE(opp)); 543 return; 544 } 545 546 opp->gcr &= ~opp->mpic_mode_mask; 547 opp->gcr |= val & opp->mpic_mode_mask; 548 549 /* Set external proxy mode */ 550 if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) { 551 mpic_proxy = true; 552 } 553 554 ppce500_set_mpic_proxy(mpic_proxy); 555 } 556 557 static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val, 558 unsigned len) 559 { 560 OpenPICState *opp = opaque; 561 IRQDest *dst; 562 int idx; 563 564 DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64, 565 __func__, addr, val); 566 if (addr & 0xF) { 567 return; 568 } 569 switch (addr) { 570 case 0x00: /* Block Revision Register1 (BRR1) is Readonly */ 571 break; 572 case 0x40: 573 case 0x50: 574 case 0x60: 575 case 0x70: 576 case 0x80: 577 case 0x90: 578 case 0xA0: 579 case 0xB0: 580 openpic_cpu_write_internal(opp, addr, val, get_current_cpu()); 581 break; 582 case 0x1000: /* FRR */ 583 break; 584 case 0x1020: /* GCR */ 585 openpic_gcr_write(opp, val); 586 break; 587 case 0x1080: /* VIR */ 588 break; 589 case 0x1090: /* PIR */ 590 for (idx = 0; idx < opp->nb_cpus; idx++) { 591 if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) { 592 DPRINTF("Raise OpenPIC RESET output for CPU %d", idx); 593 dst = &opp->dst[idx]; 594 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]); 595 } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) { 596 DPRINTF("Lower OpenPIC RESET output for CPU %d", idx); 597 dst = &opp->dst[idx]; 598 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]); 599 } 600 } 601 opp->pir = val; 602 break; 603 case 0x10A0: /* IPI_IVPR */ 604 case 0x10B0: 605 case 0x10C0: 606 case 0x10D0: 607 { 608 int idx; 609 idx = (addr - 0x10A0) >> 4; 610 write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val); 611 } 612 break; 613 case 0x10E0: /* SPVE */ 614 opp->spve = val & opp->vector_mask; 615 break; 616 default: 617 break; 618 } 619 } 620 621 static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len) 622 { 623 OpenPICState *opp = opaque; 624 uint32_t retval; 625 626 DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr); 627 retval = 0xFFFFFFFF; 628 if (addr & 0xF) { 629 return retval; 630 } 631 switch (addr) { 632 case 0x1000: /* FRR */ 633 retval = opp->frr; 634 break; 635 case 0x1020: /* GCR */ 636 retval = opp->gcr; 637 break; 638 case 0x1080: /* VIR */ 639 retval = opp->vir; 640 break; 641 case 0x1090: /* PIR */ 642 retval = 0x00000000; 643 break; 644 case 0x00: /* Block Revision Register1 (BRR1) */ 645 retval = opp->brr1; 646 break; 647 case 0x40: 648 case 0x50: 649 case 0x60: 650 case 0x70: 651 case 0x80: 652 case 0x90: 653 case 0xA0: 654 case 0xB0: 655 retval = openpic_cpu_read_internal(opp, addr, get_current_cpu()); 656 break; 657 case 0x10A0: /* IPI_IVPR */ 658 case 0x10B0: 659 case 0x10C0: 660 case 0x10D0: 661 { 662 int idx; 663 idx = (addr - 0x10A0) >> 4; 664 retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx); 665 } 666 break; 667 case 0x10E0: /* SPVE */ 668 retval = opp->spve; 669 break; 670 default: 671 break; 672 } 673 DPRINTF("%s: => 0x%08x", __func__, retval); 674 675 return retval; 676 } 677 678 static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled); 679 680 static void qemu_timer_cb(void *opaque) 681 { 682 OpenPICTimer *tmr = opaque; 683 OpenPICState *opp = tmr->opp; 684 uint32_t n_IRQ = tmr->n_IRQ; 685 uint32_t val = tmr->tbcr & ~TBCR_CI; 686 uint32_t tog = ((tmr->tccr & TCCR_TOG) ^ TCCR_TOG); /* invert toggle. */ 687 688 DPRINTF("%s n_IRQ=%d", __func__, n_IRQ); 689 /* Reload current count from base count and setup timer. */ 690 tmr->tccr = val | tog; 691 openpic_tmr_set_tmr(tmr, val, /*enabled=*/true); 692 /* Raise the interrupt. */ 693 opp->src[n_IRQ].destmask = read_IRQreg_idr(opp, n_IRQ); 694 openpic_set_irq(opp, n_IRQ, 1); 695 openpic_set_irq(opp, n_IRQ, 0); 696 } 697 698 /* If enabled is true, arranges for an interrupt to be raised val clocks into 699 the future, if enabled is false cancels the timer. */ 700 static void openpic_tmr_set_tmr(OpenPICTimer *tmr, uint32_t val, bool enabled) 701 { 702 uint64_t ns = ticks_to_ns(val & ~TCCR_TOG); 703 /* A count of zero causes a timer to be set to expire immediately. This 704 effectively stops the simulation since the timer is constantly expiring 705 which prevents guest code execution, so we don't honor that 706 configuration. On real hardware, this situation would generate an 707 interrupt on every clock cycle if the interrupt was unmasked. */ 708 if ((ns == 0) || !enabled) { 709 tmr->qemu_timer_active = false; 710 tmr->tccr = tmr->tccr & TCCR_TOG; 711 timer_del(tmr->qemu_timer); /* set timer to never expire. */ 712 } else { 713 tmr->qemu_timer_active = true; 714 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 715 tmr->origin_time = now; 716 timer_mod(tmr->qemu_timer, now + ns); /* set timer expiration. */ 717 } 718 } 719 720 /* Returns the currrent tccr value, i.e., timer value (in clocks) with 721 appropriate TOG. */ 722 static uint64_t openpic_tmr_get_timer(OpenPICTimer *tmr) 723 { 724 uint64_t retval; 725 if (!tmr->qemu_timer_active) { 726 retval = tmr->tccr; 727 } else { 728 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 729 uint64_t used = now - tmr->origin_time; /* nsecs */ 730 uint32_t used_ticks = (uint32_t)ns_to_ticks(used); 731 uint32_t count = (tmr->tccr & ~TCCR_TOG) - used_ticks; 732 retval = (uint32_t)((tmr->tccr & TCCR_TOG) | (count & ~TCCR_TOG)); 733 } 734 return retval; 735 } 736 737 static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val, 738 unsigned len) 739 { 740 OpenPICState *opp = opaque; 741 int idx; 742 743 DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64, 744 __func__, (addr + 0x10f0), val); 745 if (addr & 0xF) { 746 return; 747 } 748 749 if (addr == 0) { 750 /* TFRR */ 751 opp->tfrr = val; 752 return; 753 } 754 addr -= 0x10; /* correct for TFRR */ 755 idx = (addr >> 6) & 0x3; 756 757 switch (addr & 0x30) { 758 case 0x00: /* TCCR */ 759 break; 760 case 0x10: /* TBCR */ 761 /* Did the enable status change? */ 762 if ((opp->timers[idx].tbcr & TBCR_CI) != (val & TBCR_CI)) { 763 /* Did "Count Inhibit" transition from 1 to 0? */ 764 if ((val & TBCR_CI) == 0) { 765 opp->timers[idx].tccr = val & ~TCCR_TOG; 766 } 767 openpic_tmr_set_tmr(&opp->timers[idx], 768 (val & ~TBCR_CI), 769 /*enabled=*/((val & TBCR_CI) == 0)); 770 } 771 opp->timers[idx].tbcr = val; 772 break; 773 case 0x20: /* TVPR */ 774 write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val); 775 break; 776 case 0x30: /* TDR */ 777 write_IRQreg_idr(opp, opp->irq_tim0 + idx, val); 778 break; 779 } 780 } 781 782 static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len) 783 { 784 OpenPICState *opp = opaque; 785 uint32_t retval = -1; 786 int idx; 787 788 DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr + 0x10f0); 789 if (addr & 0xF) { 790 goto out; 791 } 792 if (addr == 0) { 793 /* TFRR */ 794 retval = opp->tfrr; 795 goto out; 796 } 797 addr -= 0x10; /* correct for TFRR */ 798 idx = (addr >> 6) & 0x3; 799 switch (addr & 0x30) { 800 case 0x00: /* TCCR */ 801 retval = openpic_tmr_get_timer(&opp->timers[idx]); 802 break; 803 case 0x10: /* TBCR */ 804 retval = opp->timers[idx].tbcr; 805 break; 806 case 0x20: /* TVPR */ 807 retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx); 808 break; 809 case 0x30: /* TDR */ 810 retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx); 811 break; 812 } 813 814 out: 815 DPRINTF("%s: => 0x%08x", __func__, retval); 816 817 return retval; 818 } 819 820 static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val, 821 unsigned len) 822 { 823 OpenPICState *opp = opaque; 824 int idx; 825 826 DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64, 827 __func__, addr, val); 828 829 addr = addr & 0xffff; 830 idx = addr >> 5; 831 832 switch (addr & 0x1f) { 833 case 0x00: 834 write_IRQreg_ivpr(opp, idx, val); 835 break; 836 case 0x10: 837 write_IRQreg_idr(opp, idx, val); 838 break; 839 case 0x18: 840 write_IRQreg_ilr(opp, idx, val); 841 break; 842 } 843 } 844 845 static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len) 846 { 847 OpenPICState *opp = opaque; 848 uint32_t retval; 849 int idx; 850 851 DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr); 852 retval = 0xFFFFFFFF; 853 854 addr = addr & 0xffff; 855 idx = addr >> 5; 856 857 switch (addr & 0x1f) { 858 case 0x00: 859 retval = read_IRQreg_ivpr(opp, idx); 860 break; 861 case 0x10: 862 retval = read_IRQreg_idr(opp, idx); 863 break; 864 case 0x18: 865 retval = read_IRQreg_ilr(opp, idx); 866 break; 867 } 868 869 DPRINTF("%s: => 0x%08x", __func__, retval); 870 return retval; 871 } 872 873 static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val, 874 unsigned size) 875 { 876 OpenPICState *opp = opaque; 877 int idx = opp->irq_msi; 878 int srs, ibs; 879 880 DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64, 881 __func__, addr, val); 882 if (addr & 0xF) { 883 return; 884 } 885 886 switch (addr) { 887 case MSIIR_OFFSET: 888 srs = val >> MSIIR_SRS_SHIFT; 889 idx += srs; 890 ibs = (val & MSIIR_IBS_MASK) >> MSIIR_IBS_SHIFT; 891 opp->msi[srs].msir |= 1 << ibs; 892 openpic_set_irq(opp, idx, 1); 893 break; 894 default: 895 /* most registers are read-only, thus ignored */ 896 break; 897 } 898 } 899 900 static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size) 901 { 902 OpenPICState *opp = opaque; 903 uint64_t r = 0; 904 int i, srs; 905 906 DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr); 907 if (addr & 0xF) { 908 return -1; 909 } 910 911 srs = addr >> 4; 912 913 switch (addr) { 914 case 0x00: 915 case 0x10: 916 case 0x20: 917 case 0x30: 918 case 0x40: 919 case 0x50: 920 case 0x60: 921 case 0x70: /* MSIRs */ 922 r = opp->msi[srs].msir; 923 /* Clear on read */ 924 opp->msi[srs].msir = 0; 925 openpic_set_irq(opp, opp->irq_msi + srs, 0); 926 break; 927 case 0x120: /* MSISR */ 928 for (i = 0; i < MAX_MSI; i++) { 929 r |= (opp->msi[i].msir ? 1 : 0) << i; 930 } 931 break; 932 } 933 934 return r; 935 } 936 937 static uint64_t openpic_summary_read(void *opaque, hwaddr addr, unsigned size) 938 { 939 uint64_t r = 0; 940 941 DPRINTF("%s: addr %#" HWADDR_PRIx, __func__, addr); 942 943 /* TODO: EISR/EIMR */ 944 945 return r; 946 } 947 948 static void openpic_summary_write(void *opaque, hwaddr addr, uint64_t val, 949 unsigned size) 950 { 951 DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64, 952 __func__, addr, val); 953 954 /* TODO: EISR/EIMR */ 955 } 956 957 static void openpic_cpu_write_internal(void *opaque, hwaddr addr, 958 uint32_t val, int idx) 959 { 960 OpenPICState *opp = opaque; 961 IRQSource *src; 962 IRQDest *dst; 963 int s_IRQ, n_IRQ; 964 965 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x", __func__, idx, 966 addr, val); 967 968 if (idx < 0 || idx >= opp->nb_cpus) { 969 return; 970 } 971 972 if (addr & 0xF) { 973 return; 974 } 975 dst = &opp->dst[idx]; 976 addr &= 0xFF0; 977 switch (addr) { 978 case 0x40: /* IPIDR */ 979 case 0x50: 980 case 0x60: 981 case 0x70: 982 idx = (addr - 0x40) >> 4; 983 /* we use IDE as mask which CPUs to deliver the IPI to still. */ 984 opp->src[opp->irq_ipi0 + idx].destmask |= val; 985 openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); 986 openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); 987 break; 988 case 0x80: /* CTPR */ 989 dst->ctpr = val & 0x0000000F; 990 991 DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d", 992 __func__, idx, dst->ctpr, dst->raised.priority, 993 dst->servicing.priority); 994 995 if (dst->raised.priority <= dst->ctpr) { 996 DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr", 997 __func__, idx); 998 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); 999 } else if (dst->raised.priority > dst->servicing.priority) { 1000 DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d", 1001 __func__, idx, dst->raised.next); 1002 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]); 1003 } 1004 1005 break; 1006 case 0x90: /* WHOAMI */ 1007 /* Read-only register */ 1008 break; 1009 case 0xA0: /* IACK */ 1010 /* Read-only register */ 1011 break; 1012 case 0xB0: /* EOI */ 1013 DPRINTF("EOI"); 1014 s_IRQ = IRQ_get_next(opp, &dst->servicing); 1015 1016 if (s_IRQ < 0) { 1017 DPRINTF("%s: EOI with no interrupt in service", __func__); 1018 break; 1019 } 1020 1021 IRQ_resetbit(&dst->servicing, s_IRQ); 1022 /* Set up next servicing IRQ */ 1023 s_IRQ = IRQ_get_next(opp, &dst->servicing); 1024 /* Check queued interrupts. */ 1025 n_IRQ = IRQ_get_next(opp, &dst->raised); 1026 src = &opp->src[n_IRQ]; 1027 if (n_IRQ != -1 && 1028 (s_IRQ == -1 || 1029 IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) { 1030 DPRINTF("Raise OpenPIC INT output cpu %d irq %d", 1031 idx, n_IRQ); 1032 qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); 1033 } 1034 break; 1035 default: 1036 break; 1037 } 1038 } 1039 1040 static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val, 1041 unsigned len) 1042 { 1043 openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12); 1044 } 1045 1046 1047 static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) 1048 { 1049 IRQSource *src; 1050 int retval, irq; 1051 1052 DPRINTF("Lower OpenPIC INT output"); 1053 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); 1054 1055 irq = IRQ_get_next(opp, &dst->raised); 1056 DPRINTF("IACK: irq=%d", irq); 1057 1058 if (irq == -1) { 1059 /* No more interrupt pending */ 1060 return opp->spve; 1061 } 1062 1063 src = &opp->src[irq]; 1064 if (!(src->ivpr & IVPR_ACTIVITY_MASK) || 1065 !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { 1066 error_report("%s: bad raised IRQ %d ctpr %d ivpr 0x%08x", 1067 __func__, irq, dst->ctpr, src->ivpr); 1068 openpic_update_irq(opp, irq); 1069 retval = opp->spve; 1070 } else { 1071 /* IRQ enter servicing state */ 1072 IRQ_setbit(&dst->servicing, irq); 1073 retval = IVPR_VECTOR(opp, src->ivpr); 1074 } 1075 1076 if (!src->level) { 1077 /* edge-sensitive IRQ */ 1078 src->ivpr &= ~IVPR_ACTIVITY_MASK; 1079 src->pending = 0; 1080 IRQ_resetbit(&dst->raised, irq); 1081 } 1082 1083 /* Timers and IPIs support multicast. */ 1084 if (((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + OPENPIC_MAX_IPI))) || 1085 ((irq >= opp->irq_tim0) && (irq < (opp->irq_tim0 + OPENPIC_MAX_TMR)))) { 1086 DPRINTF("irq is IPI or TMR"); 1087 src->destmask &= ~(1 << cpu); 1088 if (src->destmask && !src->level) { 1089 /* trigger on CPUs that didn't know about it yet */ 1090 openpic_set_irq(opp, irq, 1); 1091 openpic_set_irq(opp, irq, 0); 1092 /* if all CPUs knew about it, set active bit again */ 1093 src->ivpr |= IVPR_ACTIVITY_MASK; 1094 } 1095 } 1096 1097 return retval; 1098 } 1099 1100 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, 1101 int idx) 1102 { 1103 OpenPICState *opp = opaque; 1104 IRQDest *dst; 1105 uint32_t retval; 1106 1107 DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx, __func__, idx, addr); 1108 retval = 0xFFFFFFFF; 1109 1110 if (idx < 0 || idx >= opp->nb_cpus) { 1111 return retval; 1112 } 1113 1114 if (addr & 0xF) { 1115 return retval; 1116 } 1117 dst = &opp->dst[idx]; 1118 addr &= 0xFF0; 1119 switch (addr) { 1120 case 0x80: /* CTPR */ 1121 retval = dst->ctpr; 1122 break; 1123 case 0x90: /* WHOAMI */ 1124 retval = idx; 1125 break; 1126 case 0xA0: /* IACK */ 1127 retval = openpic_iack(opp, dst, idx); 1128 break; 1129 case 0xB0: /* EOI */ 1130 retval = 0; 1131 break; 1132 default: 1133 break; 1134 } 1135 DPRINTF("%s: => 0x%08x", __func__, retval); 1136 1137 return retval; 1138 } 1139 1140 static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len) 1141 { 1142 return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12); 1143 } 1144 1145 static const MemoryRegionOps openpic_glb_ops_le = { 1146 .write = openpic_gbl_write, 1147 .read = openpic_gbl_read, 1148 .endianness = DEVICE_LITTLE_ENDIAN, 1149 .impl = { 1150 .min_access_size = 4, 1151 .max_access_size = 4, 1152 }, 1153 }; 1154 1155 static const MemoryRegionOps openpic_glb_ops_be = { 1156 .write = openpic_gbl_write, 1157 .read = openpic_gbl_read, 1158 .endianness = DEVICE_BIG_ENDIAN, 1159 .impl = { 1160 .min_access_size = 4, 1161 .max_access_size = 4, 1162 }, 1163 }; 1164 1165 static const MemoryRegionOps openpic_tmr_ops_le = { 1166 .write = openpic_tmr_write, 1167 .read = openpic_tmr_read, 1168 .endianness = DEVICE_LITTLE_ENDIAN, 1169 .impl = { 1170 .min_access_size = 4, 1171 .max_access_size = 4, 1172 }, 1173 }; 1174 1175 static const MemoryRegionOps openpic_tmr_ops_be = { 1176 .write = openpic_tmr_write, 1177 .read = openpic_tmr_read, 1178 .endianness = DEVICE_BIG_ENDIAN, 1179 .impl = { 1180 .min_access_size = 4, 1181 .max_access_size = 4, 1182 }, 1183 }; 1184 1185 static const MemoryRegionOps openpic_cpu_ops_le = { 1186 .write = openpic_cpu_write, 1187 .read = openpic_cpu_read, 1188 .endianness = DEVICE_LITTLE_ENDIAN, 1189 .impl = { 1190 .min_access_size = 4, 1191 .max_access_size = 4, 1192 }, 1193 }; 1194 1195 static const MemoryRegionOps openpic_cpu_ops_be = { 1196 .write = openpic_cpu_write, 1197 .read = openpic_cpu_read, 1198 .endianness = DEVICE_BIG_ENDIAN, 1199 .impl = { 1200 .min_access_size = 4, 1201 .max_access_size = 4, 1202 }, 1203 }; 1204 1205 static const MemoryRegionOps openpic_src_ops_le = { 1206 .write = openpic_src_write, 1207 .read = openpic_src_read, 1208 .endianness = DEVICE_LITTLE_ENDIAN, 1209 .impl = { 1210 .min_access_size = 4, 1211 .max_access_size = 4, 1212 }, 1213 }; 1214 1215 static const MemoryRegionOps openpic_src_ops_be = { 1216 .write = openpic_src_write, 1217 .read = openpic_src_read, 1218 .endianness = DEVICE_BIG_ENDIAN, 1219 .impl = { 1220 .min_access_size = 4, 1221 .max_access_size = 4, 1222 }, 1223 }; 1224 1225 static const MemoryRegionOps openpic_msi_ops_be = { 1226 .read = openpic_msi_read, 1227 .write = openpic_msi_write, 1228 .endianness = DEVICE_BIG_ENDIAN, 1229 .impl = { 1230 .min_access_size = 4, 1231 .max_access_size = 4, 1232 }, 1233 }; 1234 1235 static const MemoryRegionOps openpic_summary_ops_be = { 1236 .read = openpic_summary_read, 1237 .write = openpic_summary_write, 1238 .endianness = DEVICE_BIG_ENDIAN, 1239 .impl = { 1240 .min_access_size = 4, 1241 .max_access_size = 4, 1242 }, 1243 }; 1244 1245 static void openpic_reset(DeviceState *d) 1246 { 1247 OpenPICState *opp = OPENPIC(d); 1248 int i; 1249 1250 opp->gcr = GCR_RESET; 1251 /* Initialise controller registers */ 1252 opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) | 1253 ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) | 1254 (opp->vid << FRR_VID_SHIFT); 1255 1256 opp->pir = 0; 1257 opp->spve = -1 & opp->vector_mask; 1258 opp->tfrr = opp->tfrr_reset; 1259 /* Initialise IRQ sources */ 1260 for (i = 0; i < opp->max_irq; i++) { 1261 opp->src[i].ivpr = opp->ivpr_reset; 1262 switch (opp->src[i].type) { 1263 case IRQ_TYPE_NORMAL: 1264 opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK); 1265 break; 1266 1267 case IRQ_TYPE_FSLINT: 1268 opp->src[i].ivpr |= IVPR_POLARITY_MASK; 1269 break; 1270 1271 case IRQ_TYPE_FSLSPECIAL: 1272 break; 1273 } 1274 1275 /* Mask all IPI interrupts for Freescale OpenPIC */ 1276 if ((opp->model == OPENPIC_MODEL_FSL_MPIC_20) || 1277 (opp->model == OPENPIC_MODEL_FSL_MPIC_42)) { 1278 if (i >= opp->irq_ipi0 && i < opp->irq_tim0) { 1279 write_IRQreg_idr(opp, i, 0); 1280 continue; 1281 } 1282 } 1283 1284 write_IRQreg_idr(opp, i, opp->idr_reset); 1285 } 1286 /* Initialise IRQ destinations */ 1287 for (i = 0; i < opp->nb_cpus; i++) { 1288 opp->dst[i].ctpr = 15; 1289 opp->dst[i].raised.next = -1; 1290 opp->dst[i].raised.priority = 0; 1291 bitmap_clear(opp->dst[i].raised.queue, 0, IRQQUEUE_SIZE_BITS); 1292 opp->dst[i].servicing.next = -1; 1293 opp->dst[i].servicing.priority = 0; 1294 bitmap_clear(opp->dst[i].servicing.queue, 0, IRQQUEUE_SIZE_BITS); 1295 } 1296 /* Initialise timers */ 1297 for (i = 0; i < OPENPIC_MAX_TMR; i++) { 1298 opp->timers[i].tccr = 0; 1299 opp->timers[i].tbcr = TBCR_CI; 1300 if (opp->timers[i].qemu_timer_active) { 1301 timer_del(opp->timers[i].qemu_timer); /* Inhibit timer */ 1302 opp->timers[i].qemu_timer_active = false; 1303 } 1304 } 1305 /* Go out of RESET state */ 1306 opp->gcr = 0; 1307 } 1308 1309 typedef struct MemReg { 1310 const char *name; 1311 MemoryRegionOps const *ops; 1312 hwaddr start_addr; 1313 ram_addr_t size; 1314 } MemReg; 1315 1316 static void fsl_common_init(OpenPICState *opp) 1317 { 1318 int i; 1319 int virq = OPENPIC_MAX_SRC; 1320 1321 opp->vid = VID_REVISION_1_2; 1322 opp->vir = VIR_GENERIC; 1323 opp->vector_mask = 0xFFFF; 1324 opp->tfrr_reset = 0; 1325 opp->ivpr_reset = IVPR_MASK_MASK; 1326 opp->idr_reset = 1 << 0; 1327 opp->max_irq = OPENPIC_MAX_IRQ; 1328 1329 opp->irq_ipi0 = virq; 1330 virq += OPENPIC_MAX_IPI; 1331 opp->irq_tim0 = virq; 1332 virq += OPENPIC_MAX_TMR; 1333 1334 assert(virq <= OPENPIC_MAX_IRQ); 1335 1336 opp->irq_msi = 224; 1337 1338 msi_nonbroken = true; 1339 for (i = 0; i < opp->fsl->max_ext; i++) { 1340 opp->src[i].level = false; 1341 } 1342 1343 /* Internal interrupts, including message and MSI */ 1344 for (i = 16; i < OPENPIC_MAX_SRC; i++) { 1345 opp->src[i].type = IRQ_TYPE_FSLINT; 1346 opp->src[i].level = true; 1347 } 1348 1349 /* timers and IPIs */ 1350 for (i = OPENPIC_MAX_SRC; i < virq; i++) { 1351 opp->src[i].type = IRQ_TYPE_FSLSPECIAL; 1352 opp->src[i].level = false; 1353 } 1354 1355 for (i = 0; i < OPENPIC_MAX_TMR; i++) { 1356 opp->timers[i].n_IRQ = opp->irq_tim0 + i; 1357 opp->timers[i].qemu_timer_active = false; 1358 opp->timers[i].qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 1359 &qemu_timer_cb, 1360 &opp->timers[i]); 1361 opp->timers[i].opp = opp; 1362 } 1363 } 1364 1365 static void map_list(OpenPICState *opp, const MemReg *list, int *count) 1366 { 1367 while (list->name) { 1368 assert(*count < ARRAY_SIZE(opp->sub_io_mem)); 1369 1370 memory_region_init_io(&opp->sub_io_mem[*count], OBJECT(opp), list->ops, 1371 opp, list->name, list->size); 1372 1373 memory_region_add_subregion(&opp->mem, list->start_addr, 1374 &opp->sub_io_mem[*count]); 1375 1376 (*count)++; 1377 list++; 1378 } 1379 } 1380 1381 static const VMStateDescription vmstate_openpic_irq_queue = { 1382 .name = "openpic_irq_queue", 1383 .version_id = 0, 1384 .minimum_version_id = 0, 1385 .fields = (VMStateField[]) { 1386 VMSTATE_BITMAP(queue, IRQQueue, 0, queue_size), 1387 VMSTATE_INT32(next, IRQQueue), 1388 VMSTATE_INT32(priority, IRQQueue), 1389 VMSTATE_END_OF_LIST() 1390 } 1391 }; 1392 1393 static const VMStateDescription vmstate_openpic_irqdest = { 1394 .name = "openpic_irqdest", 1395 .version_id = 0, 1396 .minimum_version_id = 0, 1397 .fields = (VMStateField[]) { 1398 VMSTATE_INT32(ctpr, IRQDest), 1399 VMSTATE_STRUCT(raised, IRQDest, 0, vmstate_openpic_irq_queue, 1400 IRQQueue), 1401 VMSTATE_STRUCT(servicing, IRQDest, 0, vmstate_openpic_irq_queue, 1402 IRQQueue), 1403 VMSTATE_UINT32_ARRAY(outputs_active, IRQDest, OPENPIC_OUTPUT_NB), 1404 VMSTATE_END_OF_LIST() 1405 } 1406 }; 1407 1408 static const VMStateDescription vmstate_openpic_irqsource = { 1409 .name = "openpic_irqsource", 1410 .version_id = 0, 1411 .minimum_version_id = 0, 1412 .fields = (VMStateField[]) { 1413 VMSTATE_UINT32(ivpr, IRQSource), 1414 VMSTATE_UINT32(idr, IRQSource), 1415 VMSTATE_UINT32(destmask, IRQSource), 1416 VMSTATE_INT32(last_cpu, IRQSource), 1417 VMSTATE_INT32(pending, IRQSource), 1418 VMSTATE_END_OF_LIST() 1419 } 1420 }; 1421 1422 static const VMStateDescription vmstate_openpic_timer = { 1423 .name = "openpic_timer", 1424 .version_id = 0, 1425 .minimum_version_id = 0, 1426 .fields = (VMStateField[]) { 1427 VMSTATE_UINT32(tccr, OpenPICTimer), 1428 VMSTATE_UINT32(tbcr, OpenPICTimer), 1429 VMSTATE_END_OF_LIST() 1430 } 1431 }; 1432 1433 static const VMStateDescription vmstate_openpic_msi = { 1434 .name = "openpic_msi", 1435 .version_id = 0, 1436 .minimum_version_id = 0, 1437 .fields = (VMStateField[]) { 1438 VMSTATE_UINT32(msir, OpenPICMSI), 1439 VMSTATE_END_OF_LIST() 1440 } 1441 }; 1442 1443 static int openpic_post_load(void *opaque, int version_id) 1444 { 1445 OpenPICState *opp = (OpenPICState *)opaque; 1446 int i; 1447 1448 /* Update internal ivpr and idr variables */ 1449 for (i = 0; i < opp->max_irq; i++) { 1450 write_IRQreg_idr(opp, i, opp->src[i].idr); 1451 write_IRQreg_ivpr(opp, i, opp->src[i].ivpr); 1452 } 1453 1454 return 0; 1455 } 1456 1457 static const VMStateDescription vmstate_openpic = { 1458 .name = "openpic", 1459 .version_id = 3, 1460 .minimum_version_id = 3, 1461 .post_load = openpic_post_load, 1462 .fields = (VMStateField[]) { 1463 VMSTATE_UINT32(gcr, OpenPICState), 1464 VMSTATE_UINT32(vir, OpenPICState), 1465 VMSTATE_UINT32(pir, OpenPICState), 1466 VMSTATE_UINT32(spve, OpenPICState), 1467 VMSTATE_UINT32(tfrr, OpenPICState), 1468 VMSTATE_UINT32(max_irq, OpenPICState), 1469 VMSTATE_STRUCT_VARRAY_UINT32(src, OpenPICState, max_irq, 0, 1470 vmstate_openpic_irqsource, IRQSource), 1471 VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState, NULL), 1472 VMSTATE_STRUCT_VARRAY_UINT32(dst, OpenPICState, nb_cpus, 0, 1473 vmstate_openpic_irqdest, IRQDest), 1474 VMSTATE_STRUCT_ARRAY(timers, OpenPICState, OPENPIC_MAX_TMR, 0, 1475 vmstate_openpic_timer, OpenPICTimer), 1476 VMSTATE_STRUCT_ARRAY(msi, OpenPICState, MAX_MSI, 0, 1477 vmstate_openpic_msi, OpenPICMSI), 1478 VMSTATE_UINT32(irq_ipi0, OpenPICState), 1479 VMSTATE_UINT32(irq_tim0, OpenPICState), 1480 VMSTATE_UINT32(irq_msi, OpenPICState), 1481 VMSTATE_END_OF_LIST() 1482 } 1483 }; 1484 1485 static void openpic_init(Object *obj) 1486 { 1487 OpenPICState *opp = OPENPIC(obj); 1488 1489 memory_region_init(&opp->mem, obj, "openpic", 0x40000); 1490 } 1491 1492 static void openpic_realize(DeviceState *dev, Error **errp) 1493 { 1494 SysBusDevice *d = SYS_BUS_DEVICE(dev); 1495 OpenPICState *opp = OPENPIC(dev); 1496 int i, j; 1497 int list_count = 0; 1498 static const MemReg list_le[] = { 1499 {"glb", &openpic_glb_ops_le, 1500 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, 1501 {"tmr", &openpic_tmr_ops_le, 1502 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE}, 1503 {"src", &openpic_src_ops_le, 1504 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE}, 1505 {"cpu", &openpic_cpu_ops_le, 1506 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, 1507 {NULL} 1508 }; 1509 static const MemReg list_be[] = { 1510 {"glb", &openpic_glb_ops_be, 1511 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, 1512 {"tmr", &openpic_tmr_ops_be, 1513 OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE}, 1514 {"src", &openpic_src_ops_be, 1515 OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE}, 1516 {"cpu", &openpic_cpu_ops_be, 1517 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, 1518 {NULL} 1519 }; 1520 static const MemReg list_fsl[] = { 1521 {"msi", &openpic_msi_ops_be, 1522 OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE}, 1523 {"summary", &openpic_summary_ops_be, 1524 OPENPIC_SUMMARY_REG_START, OPENPIC_SUMMARY_REG_SIZE}, 1525 {NULL} 1526 }; 1527 1528 if (opp->nb_cpus > MAX_CPU) { 1529 error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, 1530 TYPE_OPENPIC, "nb_cpus", (uint64_t)opp->nb_cpus, 1531 (uint64_t)0, (uint64_t)MAX_CPU); 1532 return; 1533 } 1534 1535 switch (opp->model) { 1536 case OPENPIC_MODEL_FSL_MPIC_20: 1537 default: 1538 opp->fsl = &fsl_mpic_20; 1539 opp->brr1 = 0x00400200; 1540 opp->flags |= OPENPIC_FLAG_IDR_CRIT; 1541 opp->nb_irqs = 80; 1542 opp->mpic_mode_mask = GCR_MODE_MIXED; 1543 1544 fsl_common_init(opp); 1545 map_list(opp, list_be, &list_count); 1546 map_list(opp, list_fsl, &list_count); 1547 1548 break; 1549 1550 case OPENPIC_MODEL_FSL_MPIC_42: 1551 opp->fsl = &fsl_mpic_42; 1552 opp->brr1 = 0x00400402; 1553 opp->flags |= OPENPIC_FLAG_ILR; 1554 opp->nb_irqs = 196; 1555 opp->mpic_mode_mask = GCR_MODE_PROXY; 1556 1557 fsl_common_init(opp); 1558 map_list(opp, list_be, &list_count); 1559 map_list(opp, list_fsl, &list_count); 1560 1561 break; 1562 1563 case OPENPIC_MODEL_KEYLARGO: 1564 opp->nb_irqs = KEYLARGO_MAX_EXT; 1565 opp->vid = VID_REVISION_1_2; 1566 opp->vir = VIR_GENERIC; 1567 opp->vector_mask = 0xFF; 1568 opp->tfrr_reset = 4160000; 1569 opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK; 1570 opp->idr_reset = 0; 1571 opp->max_irq = KEYLARGO_MAX_IRQ; 1572 opp->irq_ipi0 = KEYLARGO_IPI_IRQ; 1573 opp->irq_tim0 = KEYLARGO_TMR_IRQ; 1574 opp->brr1 = -1; 1575 opp->mpic_mode_mask = GCR_MODE_MIXED; 1576 1577 if (opp->nb_cpus != 1) { 1578 error_setg(errp, "Only UP supported today"); 1579 return; 1580 } 1581 1582 map_list(opp, list_le, &list_count); 1583 break; 1584 } 1585 1586 for (i = 0; i < opp->nb_cpus; i++) { 1587 opp->dst[i].irqs = g_new0(qemu_irq, OPENPIC_OUTPUT_NB); 1588 for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { 1589 sysbus_init_irq(d, &opp->dst[i].irqs[j]); 1590 } 1591 1592 opp->dst[i].raised.queue_size = IRQQUEUE_SIZE_BITS; 1593 opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS); 1594 opp->dst[i].servicing.queue_size = IRQQUEUE_SIZE_BITS; 1595 opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS); 1596 } 1597 1598 sysbus_init_mmio(d, &opp->mem); 1599 qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq); 1600 } 1601 1602 static Property openpic_properties[] = { 1603 DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_FSL_MPIC_20), 1604 DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1), 1605 DEFINE_PROP_END_OF_LIST(), 1606 }; 1607 1608 static void openpic_class_init(ObjectClass *oc, void *data) 1609 { 1610 DeviceClass *dc = DEVICE_CLASS(oc); 1611 1612 dc->realize = openpic_realize; 1613 device_class_set_props(dc, openpic_properties); 1614 dc->reset = openpic_reset; 1615 dc->vmsd = &vmstate_openpic; 1616 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 1617 } 1618 1619 static const TypeInfo openpic_info = { 1620 .name = TYPE_OPENPIC, 1621 .parent = TYPE_SYS_BUS_DEVICE, 1622 .instance_size = sizeof(OpenPICState), 1623 .instance_init = openpic_init, 1624 .class_init = openpic_class_init, 1625 }; 1626 1627 static void openpic_register_types(void) 1628 { 1629 type_register_static(&openpic_info); 1630 } 1631 1632 type_init(openpic_register_types) 1633