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