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