Statistics
| Branch: | Revision:

root / hw / openpic.c @ 0d09e41a

History | View | Annotate | Download (45.3 kB)

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/sysbus.h"
41
#include "hw/pci/msi.h"
42
#include "qemu/bitops.h"
43
#include "hw/ppc/ppc.h"
44

    
45
//#define DEBUG_OPENPIC
46

    
47
#ifdef DEBUG_OPENPIC
48
static const int debug_openpic = 1;
49
#else
50
static const int debug_openpic = 0;
51
#endif
52

    
53
#define DPRINTF(fmt, ...) do { \
54
        if (debug_openpic) { \
55
            printf(fmt , ## __VA_ARGS__); \
56
        } \
57
    } while (0)
58

    
59
#define MAX_CPU     32
60
#define MAX_SRC     256
61
#define MAX_TMR     4
62
#define MAX_IPI     4
63
#define MAX_MSI     8
64
#define MAX_IRQ     (MAX_SRC + MAX_IPI + MAX_TMR)
65
#define VID         0x03 /* MPIC version ID */
66

    
67
/* OpenPIC capability flags */
68
#define OPENPIC_FLAG_IDR_CRIT     (1 << 0)
69
#define OPENPIC_FLAG_ILR          (2 << 0)
70

    
71
/* OpenPIC address map */
72
#define OPENPIC_GLB_REG_START        0x0
73
#define OPENPIC_GLB_REG_SIZE         0x10F0
74
#define OPENPIC_TMR_REG_START        0x10F0
75
#define OPENPIC_TMR_REG_SIZE         0x220
76
#define OPENPIC_MSI_REG_START        0x1600
77
#define OPENPIC_MSI_REG_SIZE         0x200
78
#define OPENPIC_SUMMARY_REG_START   0x3800
79
#define OPENPIC_SUMMARY_REG_SIZE    0x800
80
#define OPENPIC_SRC_REG_START        0x10000
81
#define OPENPIC_SRC_REG_SIZE         (MAX_SRC * 0x20)
82
#define OPENPIC_CPU_REG_START        0x20000
83
#define OPENPIC_CPU_REG_SIZE         0x100 + ((MAX_CPU - 1) * 0x1000)
84

    
85
/* Raven */
86
#define RAVEN_MAX_CPU      2
87
#define RAVEN_MAX_EXT     48
88
#define RAVEN_MAX_IRQ     64
89
#define RAVEN_MAX_TMR      MAX_TMR
90
#define RAVEN_MAX_IPI      MAX_IPI
91

    
92
/* Interrupt definitions */
93
#define RAVEN_FE_IRQ     (RAVEN_MAX_EXT)     /* Internal functional IRQ */
94
#define RAVEN_ERR_IRQ    (RAVEN_MAX_EXT + 1) /* Error IRQ */
95
#define RAVEN_TMR_IRQ    (RAVEN_MAX_EXT + 2) /* First timer IRQ */
96
#define RAVEN_IPI_IRQ    (RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */
97
/* First doorbell IRQ */
98
#define RAVEN_DBL_IRQ    (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI))
99

    
100
typedef struct FslMpicInfo {
101
    int max_ext;
102
} FslMpicInfo;
103

    
104
static FslMpicInfo fsl_mpic_20 = {
105
    .max_ext = 12,
106
};
107

    
108
static FslMpicInfo fsl_mpic_42 = {
109
    .max_ext = 12,
110
};
111

    
112
#define FRR_NIRQ_SHIFT    16
113
#define FRR_NCPU_SHIFT     8
114
#define FRR_VID_SHIFT      0
115

    
116
#define VID_REVISION_1_2   2
117
#define VID_REVISION_1_3   3
118

    
119
#define VIR_GENERIC      0x00000000 /* Generic Vendor ID */
120

    
121
#define GCR_RESET        0x80000000
122
#define GCR_MODE_PASS    0x00000000
123
#define GCR_MODE_MIXED   0x20000000
124
#define GCR_MODE_PROXY   0x60000000
125

    
126
#define TBCR_CI           0x80000000 /* count inhibit */
127
#define TCCR_TOG          0x80000000 /* toggles when decrement to zero */
128

    
129
#define IDR_EP_SHIFT      31
130
#define IDR_EP_MASK       (1 << IDR_EP_SHIFT)
131
#define IDR_CI0_SHIFT     30
132
#define IDR_CI1_SHIFT     29
133
#define IDR_P1_SHIFT      1
134
#define IDR_P0_SHIFT      0
135

    
136
#define ILR_INTTGT_MASK   0x000000ff
137
#define ILR_INTTGT_INT    0x00
138
#define ILR_INTTGT_CINT   0x01 /* critical */
139
#define ILR_INTTGT_MCP    0x02 /* machine check */
140

    
141
/* The currently supported INTTGT values happen to be the same as QEMU's
142
 * openpic output codes, but don't depend on this.  The output codes
143
 * could change (unlikely, but...) or support could be added for
144
 * more INTTGT values.
145
 */
146
static const int inttgt_output[][2] = {
147
    { ILR_INTTGT_INT, OPENPIC_OUTPUT_INT },
148
    { ILR_INTTGT_CINT, OPENPIC_OUTPUT_CINT },
149
    { ILR_INTTGT_MCP, OPENPIC_OUTPUT_MCK },
150
};
151

    
152
static int inttgt_to_output(int inttgt)
153
{
154
    int i;
155

    
156
    for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
157
        if (inttgt_output[i][0] == inttgt) {
158
            return inttgt_output[i][1];
159
        }
160
    }
161

    
162
    fprintf(stderr, "%s: unsupported inttgt %d\n", __func__, inttgt);
163
    return OPENPIC_OUTPUT_INT;
164
}
165

    
166
static int output_to_inttgt(int output)
167
{
168
    int i;
169

    
170
    for (i = 0; i < ARRAY_SIZE(inttgt_output); i++) {
171
        if (inttgt_output[i][1] == output) {
172
            return inttgt_output[i][0];
173
        }
174
    }
175

    
176
    abort();
177
}
178

    
179
#define MSIIR_OFFSET       0x140
180
#define MSIIR_SRS_SHIFT    29
181
#define MSIIR_SRS_MASK     (0x7 << MSIIR_SRS_SHIFT)
182
#define MSIIR_IBS_SHIFT    24
183
#define MSIIR_IBS_MASK     (0x1f << MSIIR_IBS_SHIFT)
184

    
185
static int get_current_cpu(void)
186
{
187
    CPUState *cpu_single_cpu;
188

    
189
    if (!cpu_single_env) {
190
        return -1;
191
    }
192

    
193
    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
194
    return cpu_single_cpu->cpu_index;
195
}
196

    
197
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
198
                                          int idx);
199
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
200
                                       uint32_t val, int idx);
201

    
202
typedef enum IRQType {
203
    IRQ_TYPE_NORMAL = 0,
204
    IRQ_TYPE_FSLINT,        /* FSL internal interrupt -- level only */
205
    IRQ_TYPE_FSLSPECIAL,    /* FSL timer/IPI interrupt, edge, no polarity */
206
} IRQType;
207

    
208
typedef struct IRQQueue {
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
    unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) & ~63)];
213
    int next;
214
    int priority;
215
} IRQQueue;
216

    
217
typedef struct IRQSource {
218
    uint32_t ivpr;  /* IRQ vector/priority register */
219
    uint32_t idr;   /* IRQ destination register */
220
    uint32_t destmask; /* bitmap of CPU destinations */
221
    int last_cpu;
222
    int output;     /* IRQ level, e.g. OPENPIC_OUTPUT_INT */
223
    int pending;    /* TRUE if IRQ is pending */
224
    IRQType type;
225
    bool level:1;   /* level-triggered */
226
    bool nomask:1;  /* critical interrupts ignore mask on some FSL MPICs */
227
} IRQSource;
228

    
229
#define IVPR_MASK_SHIFT       31
230
#define IVPR_MASK_MASK        (1 << IVPR_MASK_SHIFT)
231
#define IVPR_ACTIVITY_SHIFT   30
232
#define IVPR_ACTIVITY_MASK    (1 << IVPR_ACTIVITY_SHIFT)
233
#define IVPR_MODE_SHIFT       29
234
#define IVPR_MODE_MASK        (1 << IVPR_MODE_SHIFT)
235
#define IVPR_POLARITY_SHIFT   23
236
#define IVPR_POLARITY_MASK    (1 << IVPR_POLARITY_SHIFT)
237
#define IVPR_SENSE_SHIFT      22
238
#define IVPR_SENSE_MASK       (1 << IVPR_SENSE_SHIFT)
239

    
240
#define IVPR_PRIORITY_MASK     (0xF << 16)
241
#define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16))
242
#define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask)
243

    
244
/* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */
245
#define IDR_EP      0x80000000  /* external pin */
246
#define IDR_CI      0x40000000  /* critical interrupt */
247

    
248
typedef struct IRQDest {
249
    int32_t ctpr; /* CPU current task priority */
250
    IRQQueue raised;
251
    IRQQueue servicing;
252
    qemu_irq *irqs;
253

    
254
    /* Count of IRQ sources asserting on non-INT outputs */
255
    uint32_t outputs_active[OPENPIC_OUTPUT_NB];
256
} IRQDest;
257

    
258
typedef struct OpenPICState {
259
    SysBusDevice busdev;
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[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[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 inline int IRQ_testbit(IRQQueue *q, int n_IRQ)
316
{
317
    return test_bit(n_IRQ, q->queue);
318
}
319

    
320
static void IRQ_check(OpenPICState *opp, IRQQueue *q)
321
{
322
    int irq = -1;
323
    int next = -1;
324
    int priority = -1;
325

    
326
    for (;;) {
327
        irq = find_next_bit(q->queue, opp->max_irq, irq + 1);
328
        if (irq == opp->max_irq) {
329
            break;
330
        }
331

    
332
        DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n",
333
                irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority);
334

    
335
        if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) {
336
            next = irq;
337
            priority = IVPR_PRIORITY(opp->src[irq].ivpr);
338
        }
339
    }
340

    
341
    q->next = next;
342
    q->priority = priority;
343
}
344

    
345
static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)
346
{
347
    /* XXX: optimize */
348
    IRQ_check(opp, q);
349

    
350
    return q->next;
351
}
352

    
353
static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ,
354
                           bool active, bool was_active)
355
{
356
    IRQDest *dst;
357
    IRQSource *src;
358
    int priority;
359

    
360
    dst = &opp->dst[n_CPU];
361
    src = &opp->src[n_IRQ];
362

    
363
    DPRINTF("%s: IRQ %d active %d was %d\n",
364
            __func__, n_IRQ, active, was_active);
365

    
366
    if (src->output != OPENPIC_OUTPUT_INT) {
367
        DPRINTF("%s: output %d irq %d active %d was %d count %d\n",
368
                __func__, src->output, n_IRQ, active, was_active,
369
                dst->outputs_active[src->output]);
370

    
371
        /* On Freescale MPIC, critical interrupts ignore priority,
372
         * IACK, EOI, etc.  Before MPIC v4.1 they also ignore
373
         * masking.
374
         */
375
        if (active) {
376
            if (!was_active && dst->outputs_active[src->output]++ == 0) {
377
                DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d\n",
378
                        __func__, src->output, n_CPU, n_IRQ);
379
                qemu_irq_raise(dst->irqs[src->output]);
380
            }
381
        } else {
382
            if (was_active && --dst->outputs_active[src->output] == 0) {
383
                DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d\n",
384
                        __func__, src->output, n_CPU, n_IRQ);
385
                qemu_irq_lower(dst->irqs[src->output]);
386
            }
387
        }
388

    
389
        return;
390
    }
391

    
392
    priority = IVPR_PRIORITY(src->ivpr);
393

    
394
    /* Even if the interrupt doesn't have enough priority,
395
     * it is still raised, in case ctpr is lowered later.
396
     */
397
    if (active) {
398
        IRQ_setbit(&dst->raised, n_IRQ);
399
    } else {
400
        IRQ_resetbit(&dst->raised, n_IRQ);
401
    }
402

    
403
    IRQ_check(opp, &dst->raised);
404

    
405
    if (active && priority <= dst->ctpr) {
406
        DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d\n",
407
                __func__, n_IRQ, priority, dst->ctpr, n_CPU);
408
        active = 0;
409
    }
410

    
411
    if (active) {
412
        if (IRQ_get_next(opp, &dst->servicing) >= 0 &&
413
                priority <= dst->servicing.priority) {
414
            DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
415
                    __func__, n_IRQ, dst->servicing.next, n_CPU);
416
        } else {
417
            DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d\n",
418
                    __func__, n_CPU, n_IRQ, dst->raised.next);
419
            qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
420
        }
421
    } else {
422
        IRQ_get_next(opp, &dst->servicing);
423
        if (dst->raised.priority > dst->ctpr &&
424
                dst->raised.priority > dst->servicing.priority) {
425
            DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d\n",
426
                    __func__, n_IRQ, dst->raised.next, dst->raised.priority,
427
                    dst->ctpr, dst->servicing.priority, n_CPU);
428
            /* IRQ line stays asserted */
429
        } else {
430
            DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d\n",
431
                    __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU);
432
            qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
433
        }
434
    }
435
}
436

    
437
/* update pic state because registers for n_IRQ have changed value */
438
static void openpic_update_irq(OpenPICState *opp, int n_IRQ)
439
{
440
    IRQSource *src;
441
    bool active, was_active;
442
    int i;
443

    
444
    src = &opp->src[n_IRQ];
445
    active = src->pending;
446

    
447
    if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) {
448
        /* Interrupt source is disabled */
449
        DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);
450
        active = false;
451
    }
452

    
453
    was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK);
454

    
455
    /*
456
     * We don't have a similar check for already-active because
457
     * ctpr may have changed and we need to withdraw the interrupt.
458
     */
459
    if (!active && !was_active) {
460
        DPRINTF("%s: IRQ %d is already inactive\n", __func__, n_IRQ);
461
        return;
462
    }
463

    
464
    if (active) {
465
        src->ivpr |= IVPR_ACTIVITY_MASK;
466
    } else {
467
        src->ivpr &= ~IVPR_ACTIVITY_MASK;
468
    }
469

    
470
    if (src->destmask == 0) {
471
        /* No target */
472
        DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);
473
        return;
474
    }
475

    
476
    if (src->destmask == (1 << src->last_cpu)) {
477
        /* Only one CPU is allowed to receive this IRQ */
478
        IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active);
479
    } else if (!(src->ivpr & IVPR_MODE_MASK)) {
480
        /* Directed delivery mode */
481
        for (i = 0; i < opp->nb_cpus; i++) {
482
            if (src->destmask & (1 << i)) {
483
                IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
484
            }
485
        }
486
    } else {
487
        /* Distributed delivery mode */
488
        for (i = src->last_cpu + 1; i != src->last_cpu; i++) {
489
            if (i == opp->nb_cpus) {
490
                i = 0;
491
            }
492
            if (src->destmask & (1 << i)) {
493
                IRQ_local_pipe(opp, i, n_IRQ, active, was_active);
494
                src->last_cpu = i;
495
                break;
496
            }
497
        }
498
    }
499
}
500

    
501
static void openpic_set_irq(void *opaque, int n_IRQ, int level)
502
{
503
    OpenPICState *opp = opaque;
504
    IRQSource *src;
505

    
506
    if (n_IRQ >= MAX_IRQ) {
507
        fprintf(stderr, "%s: IRQ %d out of range\n", __func__, n_IRQ);
508
        abort();
509
    }
510

    
511
    src = &opp->src[n_IRQ];
512
    DPRINTF("openpic: set irq %d = %d ivpr=0x%08x\n",
513
            n_IRQ, level, src->ivpr);
514
    if (src->level) {
515
        /* level-sensitive irq */
516
        src->pending = level;
517
        openpic_update_irq(opp, n_IRQ);
518
    } else {
519
        /* edge-sensitive irq */
520
        if (level) {
521
            src->pending = 1;
522
            openpic_update_irq(opp, n_IRQ);
523
        }
524

    
525
        if (src->output != OPENPIC_OUTPUT_INT) {
526
            /* Edge-triggered interrupts shouldn't be used
527
             * with non-INT delivery, but just in case,
528
             * try to make it do something sane rather than
529
             * cause an interrupt storm.  This is close to
530
             * what you'd probably see happen in real hardware.
531
             */
532
            src->pending = 0;
533
            openpic_update_irq(opp, n_IRQ);
534
        }
535
    }
536
}
537

    
538
static void openpic_reset(DeviceState *d)
539
{
540
    OpenPICState *opp = FROM_SYSBUS(typeof(*opp), SYS_BUS_DEVICE(d));
541
    int i;
542

    
543
    opp->gcr = GCR_RESET;
544
    /* Initialise controller registers */
545
    opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) |
546
               ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) |
547
               (opp->vid << FRR_VID_SHIFT);
548

    
549
    opp->pir = 0;
550
    opp->spve = -1 & opp->vector_mask;
551
    opp->tfrr = opp->tfrr_reset;
552
    /* Initialise IRQ sources */
553
    for (i = 0; i < opp->max_irq; i++) {
554
        opp->src[i].ivpr = opp->ivpr_reset;
555
        opp->src[i].idr  = opp->idr_reset;
556

    
557
        switch (opp->src[i].type) {
558
        case IRQ_TYPE_NORMAL:
559
            opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK);
560
            break;
561

    
562
        case IRQ_TYPE_FSLINT:
563
            opp->src[i].ivpr |= IVPR_POLARITY_MASK;
564
            break;
565

    
566
        case IRQ_TYPE_FSLSPECIAL:
567
            break;
568
        }
569
    }
570
    /* Initialise IRQ destinations */
571
    for (i = 0; i < MAX_CPU; i++) {
572
        opp->dst[i].ctpr      = 15;
573
        memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
574
        opp->dst[i].raised.next = -1;
575
        memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
576
        opp->dst[i].servicing.next = -1;
577
    }
578
    /* Initialise timers */
579
    for (i = 0; i < MAX_TMR; i++) {
580
        opp->timers[i].tccr = 0;
581
        opp->timers[i].tbcr = TBCR_CI;
582
    }
583
    /* Go out of RESET state */
584
    opp->gcr = 0;
585
}
586

    
587
static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ)
588
{
589
    return opp->src[n_IRQ].idr;
590
}
591

    
592
static inline uint32_t read_IRQreg_ilr(OpenPICState *opp, int n_IRQ)
593
{
594
    if (opp->flags & OPENPIC_FLAG_ILR) {
595
        return output_to_inttgt(opp->src[n_IRQ].output);
596
    }
597

    
598
    return 0xffffffff;
599
}
600

    
601
static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)
602
{
603
    return opp->src[n_IRQ].ivpr;
604
}
605

    
606
static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)
607
{
608
    IRQSource *src = &opp->src[n_IRQ];
609
    uint32_t normal_mask = (1UL << opp->nb_cpus) - 1;
610
    uint32_t crit_mask = 0;
611
    uint32_t mask = normal_mask;
612
    int crit_shift = IDR_EP_SHIFT - opp->nb_cpus;
613
    int i;
614

    
615
    if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
616
        crit_mask = mask << crit_shift;
617
        mask |= crit_mask | IDR_EP;
618
    }
619

    
620
    src->idr = val & mask;
621
    DPRINTF("Set IDR %d to 0x%08x\n", n_IRQ, src->idr);
622

    
623
    if (opp->flags & OPENPIC_FLAG_IDR_CRIT) {
624
        if (src->idr & crit_mask) {
625
            if (src->idr & normal_mask) {
626
                DPRINTF("%s: IRQ configured for multiple output types, using "
627
                        "critical\n", __func__);
628
            }
629

    
630
            src->output = OPENPIC_OUTPUT_CINT;
631
            src->nomask = true;
632
            src->destmask = 0;
633

    
634
            for (i = 0; i < opp->nb_cpus; i++) {
635
                int n_ci = IDR_CI0_SHIFT - i;
636

    
637
                if (src->idr & (1UL << n_ci)) {
638
                    src->destmask |= 1UL << i;
639
                }
640
            }
641
        } else {
642
            src->output = OPENPIC_OUTPUT_INT;
643
            src->nomask = false;
644
            src->destmask = src->idr & normal_mask;
645
        }
646
    } else {
647
        src->destmask = src->idr;
648
    }
649
}
650

    
651
static inline void write_IRQreg_ilr(OpenPICState *opp, int n_IRQ, uint32_t val)
652
{
653
    if (opp->flags & OPENPIC_FLAG_ILR) {
654
        IRQSource *src = &opp->src[n_IRQ];
655

    
656
        src->output = inttgt_to_output(val & ILR_INTTGT_MASK);
657
        DPRINTF("Set ILR %d to 0x%08x, output %d\n", n_IRQ, src->idr,
658
                src->output);
659

    
660
        /* TODO: on MPIC v4.0 only, set nomask for non-INT */
661
    }
662
}
663

    
664
static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
665
{
666
    uint32_t mask;
667

    
668
    /* NOTE when implementing newer FSL MPIC models: starting with v4.0,
669
     * the polarity bit is read-only on internal interrupts.
670
     */
671
    mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK |
672
           IVPR_POLARITY_MASK | opp->vector_mask;
673

    
674
    /* ACTIVITY bit is read-only */
675
    opp->src[n_IRQ].ivpr =
676
        (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask);
677

    
678
    /* For FSL internal interrupts, The sense bit is reserved and zero,
679
     * and the interrupt is always level-triggered.  Timers and IPIs
680
     * have no sense or polarity bits, and are edge-triggered.
681
     */
682
    switch (opp->src[n_IRQ].type) {
683
    case IRQ_TYPE_NORMAL:
684
        opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK);
685
        break;
686

    
687
    case IRQ_TYPE_FSLINT:
688
        opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK;
689
        break;
690

    
691
    case IRQ_TYPE_FSLSPECIAL:
692
        opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK);
693
        break;
694
    }
695

    
696
    openpic_update_irq(opp, n_IRQ);
697
    DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x\n", n_IRQ, val,
698
            opp->src[n_IRQ].ivpr);
699
}
700

    
701
static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
702
{
703
    bool mpic_proxy = false;
704

    
705
    if (val & GCR_RESET) {
706
        openpic_reset(&opp->busdev.qdev);
707
        return;
708
    }
709

    
710
    opp->gcr &= ~opp->mpic_mode_mask;
711
    opp->gcr |= val & opp->mpic_mode_mask;
712

    
713
    /* Set external proxy mode */
714
    if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
715
        mpic_proxy = true;
716
    }
717

    
718
    ppce500_set_mpic_proxy(mpic_proxy);
719
}
720

    
721
static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
722
                              unsigned len)
723
{
724
    OpenPICState *opp = opaque;
725
    IRQDest *dst;
726
    int idx;
727

    
728
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
729
            __func__, addr, val);
730
    if (addr & 0xF) {
731
        return;
732
    }
733
    switch (addr) {
734
    case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
735
        break;
736
    case 0x40:
737
    case 0x50:
738
    case 0x60:
739
    case 0x70:
740
    case 0x80:
741
    case 0x90:
742
    case 0xA0:
743
    case 0xB0:
744
        openpic_cpu_write_internal(opp, addr, val, get_current_cpu());
745
        break;
746
    case 0x1000: /* FRR */
747
        break;
748
    case 0x1020: /* GCR */
749
        openpic_gcr_write(opp, val);
750
        break;
751
    case 0x1080: /* VIR */
752
        break;
753
    case 0x1090: /* PIR */
754
        for (idx = 0; idx < opp->nb_cpus; idx++) {
755
            if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) {
756
                DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);
757
                dst = &opp->dst[idx];
758
                qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);
759
            } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) {
760
                DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);
761
                dst = &opp->dst[idx];
762
                qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);
763
            }
764
        }
765
        opp->pir = val;
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
            write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val);
775
        }
776
        break;
777
    case 0x10E0: /* SPVE */
778
        opp->spve = val & opp->vector_mask;
779
        break;
780
    default:
781
        break;
782
    }
783
}
784

    
785
static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)
786
{
787
    OpenPICState *opp = opaque;
788
    uint32_t retval;
789

    
790
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
791
    retval = 0xFFFFFFFF;
792
    if (addr & 0xF) {
793
        return retval;
794
    }
795
    switch (addr) {
796
    case 0x1000: /* FRR */
797
        retval = opp->frr;
798
        break;
799
    case 0x1020: /* GCR */
800
        retval = opp->gcr;
801
        break;
802
    case 0x1080: /* VIR */
803
        retval = opp->vir;
804
        break;
805
    case 0x1090: /* PIR */
806
        retval = 0x00000000;
807
        break;
808
    case 0x00: /* Block Revision Register1 (BRR1) */
809
        retval = opp->brr1;
810
        break;
811
    case 0x40:
812
    case 0x50:
813
    case 0x60:
814
    case 0x70:
815
    case 0x80:
816
    case 0x90:
817
    case 0xA0:
818
    case 0xB0:
819
        retval = openpic_cpu_read_internal(opp, addr, get_current_cpu());
820
        break;
821
    case 0x10A0: /* IPI_IVPR */
822
    case 0x10B0:
823
    case 0x10C0:
824
    case 0x10D0:
825
        {
826
            int idx;
827
            idx = (addr - 0x10A0) >> 4;
828
            retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx);
829
        }
830
        break;
831
    case 0x10E0: /* SPVE */
832
        retval = opp->spve;
833
        break;
834
    default:
835
        break;
836
    }
837
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
838

    
839
    return retval;
840
}
841

    
842
static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,
843
                                unsigned len)
844
{
845
    OpenPICState *opp = opaque;
846
    int idx;
847

    
848
    addr += 0x10f0;
849

    
850
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
851
            __func__, addr, val);
852
    if (addr & 0xF) {
853
        return;
854
    }
855

    
856
    if (addr == 0x10f0) {
857
        /* TFRR */
858
        opp->tfrr = val;
859
        return;
860
    }
861

    
862
    idx = (addr >> 6) & 0x3;
863
    addr = addr & 0x30;
864

    
865
    switch (addr & 0x30) {
866
    case 0x00: /* TCCR */
867
        break;
868
    case 0x10: /* TBCR */
869
        if ((opp->timers[idx].tccr & TCCR_TOG) != 0 &&
870
            (val & TBCR_CI) == 0 &&
871
            (opp->timers[idx].tbcr & TBCR_CI) != 0) {
872
            opp->timers[idx].tccr &= ~TCCR_TOG;
873
        }
874
        opp->timers[idx].tbcr = val;
875
        break;
876
    case 0x20: /* TVPR */
877
        write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val);
878
        break;
879
    case 0x30: /* TDR */
880
        write_IRQreg_idr(opp, opp->irq_tim0 + idx, val);
881
        break;
882
    }
883
}
884

    
885
static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)
886
{
887
    OpenPICState *opp = opaque;
888
    uint32_t retval = -1;
889
    int idx;
890

    
891
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
892
    if (addr & 0xF) {
893
        goto out;
894
    }
895
    idx = (addr >> 6) & 0x3;
896
    if (addr == 0x0) {
897
        /* TFRR */
898
        retval = opp->tfrr;
899
        goto out;
900
    }
901
    switch (addr & 0x30) {
902
    case 0x00: /* TCCR */
903
        retval = opp->timers[idx].tccr;
904
        break;
905
    case 0x10: /* TBCR */
906
        retval = opp->timers[idx].tbcr;
907
        break;
908
    case 0x20: /* TIPV */
909
        retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx);
910
        break;
911
    case 0x30: /* TIDE (TIDR) */
912
        retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx);
913
        break;
914
    }
915

    
916
out:
917
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
918

    
919
    return retval;
920
}
921

    
922
static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,
923
                              unsigned len)
924
{
925
    OpenPICState *opp = opaque;
926
    int idx;
927

    
928
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",
929
            __func__, addr, val);
930

    
931
    addr = addr & 0xffff;
932
    idx = addr >> 5;
933

    
934
    switch (addr & 0x1f) {
935
    case 0x00:
936
        write_IRQreg_ivpr(opp, idx, val);
937
        break;
938
    case 0x10:
939
        write_IRQreg_idr(opp, idx, val);
940
        break;
941
    case 0x18:
942
        write_IRQreg_ilr(opp, idx, val);
943
        break;
944
    }
945
}
946

    
947
static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)
948
{
949
    OpenPICState *opp = opaque;
950
    uint32_t retval;
951
    int idx;
952

    
953
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
954
    retval = 0xFFFFFFFF;
955

    
956
    addr = addr & 0xffff;
957
    idx = addr >> 5;
958

    
959
    switch (addr & 0x1f) {
960
    case 0x00:
961
        retval = read_IRQreg_ivpr(opp, idx);
962
        break;
963
    case 0x10:
964
        retval = read_IRQreg_idr(opp, idx);
965
        break;
966
    case 0x18:
967
        retval = read_IRQreg_ilr(opp, idx);
968
        break;
969
    }
970

    
971
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
972
    return retval;
973
}
974

    
975
static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,
976
                              unsigned size)
977
{
978
    OpenPICState *opp = opaque;
979
    int idx = opp->irq_msi;
980
    int srs, ibs;
981

    
982
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
983
            __func__, addr, val);
984
    if (addr & 0xF) {
985
        return;
986
    }
987

    
988
    switch (addr) {
989
    case MSIIR_OFFSET:
990
        srs = val >> MSIIR_SRS_SHIFT;
991
        idx += srs;
992
        ibs = (val & MSIIR_IBS_MASK) >> MSIIR_IBS_SHIFT;
993
        opp->msi[srs].msir |= 1 << ibs;
994
        openpic_set_irq(opp, idx, 1);
995
        break;
996
    default:
997
        /* most registers are read-only, thus ignored */
998
        break;
999
    }
1000
}
1001

    
1002
static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)
1003
{
1004
    OpenPICState *opp = opaque;
1005
    uint64_t r = 0;
1006
    int i, srs;
1007

    
1008
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
1009
    if (addr & 0xF) {
1010
        return -1;
1011
    }
1012

    
1013
    srs = addr >> 4;
1014

    
1015
    switch (addr) {
1016
    case 0x00:
1017
    case 0x10:
1018
    case 0x20:
1019
    case 0x30:
1020
    case 0x40:
1021
    case 0x50:
1022
    case 0x60:
1023
    case 0x70: /* MSIRs */
1024
        r = opp->msi[srs].msir;
1025
        /* Clear on read */
1026
        opp->msi[srs].msir = 0;
1027
        openpic_set_irq(opp, opp->irq_msi + srs, 0);
1028
        break;
1029
    case 0x120: /* MSISR */
1030
        for (i = 0; i < MAX_MSI; i++) {
1031
            r |= (opp->msi[i].msir ? 1 : 0) << i;
1032
        }
1033
        break;
1034
    }
1035

    
1036
    return r;
1037
}
1038

    
1039
static uint64_t openpic_summary_read(void *opaque, hwaddr addr, unsigned size)
1040
{
1041
    uint64_t r = 0;
1042

    
1043
    DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr);
1044

    
1045
    /* TODO: EISR/EIMR */
1046

    
1047
    return r;
1048
}
1049

    
1050
static void openpic_summary_write(void *opaque, hwaddr addr, uint64_t val,
1051
                                  unsigned size)
1052
{
1053
    DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n",
1054
            __func__, addr, val);
1055

    
1056
    /* TODO: EISR/EIMR */
1057
}
1058

    
1059
static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
1060
                                       uint32_t val, int idx)
1061
{
1062
    OpenPICState *opp = opaque;
1063
    IRQSource *src;
1064
    IRQDest *dst;
1065
    int s_IRQ, n_IRQ;
1066

    
1067
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x\n", __func__, idx,
1068
            addr, val);
1069

    
1070
    if (idx < 0) {
1071
        return;
1072
    }
1073

    
1074
    if (addr & 0xF) {
1075
        return;
1076
    }
1077
    dst = &opp->dst[idx];
1078
    addr &= 0xFF0;
1079
    switch (addr) {
1080
    case 0x40: /* IPIDR */
1081
    case 0x50:
1082
    case 0x60:
1083
    case 0x70:
1084
        idx = (addr - 0x40) >> 4;
1085
        /* we use IDE as mask which CPUs to deliver the IPI to still. */
1086
        opp->src[opp->irq_ipi0 + idx].destmask |= val;
1087
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);
1088
        openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);
1089
        break;
1090
    case 0x80: /* CTPR */
1091
        dst->ctpr = val & 0x0000000F;
1092

    
1093
        DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d\n",
1094
                __func__, idx, dst->ctpr, dst->raised.priority,
1095
                dst->servicing.priority);
1096

    
1097
        if (dst->raised.priority <= dst->ctpr) {
1098
            DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr\n",
1099
                    __func__, idx);
1100
            qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
1101
        } else if (dst->raised.priority > dst->servicing.priority) {
1102
            DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d\n",
1103
                    __func__, idx, dst->raised.next);
1104
            qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]);
1105
        }
1106

    
1107
        break;
1108
    case 0x90: /* WHOAMI */
1109
        /* Read-only register */
1110
        break;
1111
    case 0xA0: /* IACK */
1112
        /* Read-only register */
1113
        break;
1114
    case 0xB0: /* EOI */
1115
        DPRINTF("EOI\n");
1116
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
1117

    
1118
        if (s_IRQ < 0) {
1119
            DPRINTF("%s: EOI with no interrupt in service\n", __func__);
1120
            break;
1121
        }
1122

    
1123
        IRQ_resetbit(&dst->servicing, s_IRQ);
1124
        /* Set up next servicing IRQ */
1125
        s_IRQ = IRQ_get_next(opp, &dst->servicing);
1126
        /* Check queued interrupts. */
1127
        n_IRQ = IRQ_get_next(opp, &dst->raised);
1128
        src = &opp->src[n_IRQ];
1129
        if (n_IRQ != -1 &&
1130
            (s_IRQ == -1 ||
1131
             IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) {
1132
            DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
1133
                    idx, n_IRQ);
1134
            qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]);
1135
        }
1136
        break;
1137
    default:
1138
        break;
1139
    }
1140
}
1141

    
1142
static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,
1143
                              unsigned len)
1144
{
1145
    openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12);
1146
}
1147

    
1148

    
1149
static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu)
1150
{
1151
    IRQSource *src;
1152
    int retval, irq;
1153

    
1154
    DPRINTF("Lower OpenPIC INT output\n");
1155
    qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);
1156

    
1157
    irq = IRQ_get_next(opp, &dst->raised);
1158
    DPRINTF("IACK: irq=%d\n", irq);
1159

    
1160
    if (irq == -1) {
1161
        /* No more interrupt pending */
1162
        return opp->spve;
1163
    }
1164

    
1165
    src = &opp->src[irq];
1166
    if (!(src->ivpr & IVPR_ACTIVITY_MASK) ||
1167
            !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) {
1168
        fprintf(stderr, "%s: bad raised IRQ %d ctpr %d ivpr 0x%08x\n",
1169
                __func__, irq, dst->ctpr, src->ivpr);
1170
        openpic_update_irq(opp, irq);
1171
        retval = opp->spve;
1172
    } else {
1173
        /* IRQ enter servicing state */
1174
        IRQ_setbit(&dst->servicing, irq);
1175
        retval = IVPR_VECTOR(opp, src->ivpr);
1176
    }
1177

    
1178
    if (!src->level) {
1179
        /* edge-sensitive IRQ */
1180
        src->ivpr &= ~IVPR_ACTIVITY_MASK;
1181
        src->pending = 0;
1182
        IRQ_resetbit(&dst->raised, irq);
1183
    }
1184

    
1185
    if ((irq >= opp->irq_ipi0) &&  (irq < (opp->irq_ipi0 + MAX_IPI))) {
1186
        src->destmask &= ~(1 << cpu);
1187
        if (src->destmask && !src->level) {
1188
            /* trigger on CPUs that didn't know about it yet */
1189
            openpic_set_irq(opp, irq, 1);
1190
            openpic_set_irq(opp, irq, 0);
1191
            /* if all CPUs knew about it, set active bit again */
1192
            src->ivpr |= IVPR_ACTIVITY_MASK;
1193
        }
1194
    }
1195

    
1196
    return retval;
1197
}
1198

    
1199
static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
1200
                                          int idx)
1201
{
1202
    OpenPICState *opp = opaque;
1203
    IRQDest *dst;
1204
    uint32_t retval;
1205

    
1206
    DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
1207
    retval = 0xFFFFFFFF;
1208

    
1209
    if (idx < 0) {
1210
        return retval;
1211
    }
1212

    
1213
    if (addr & 0xF) {
1214
        return retval;
1215
    }
1216
    dst = &opp->dst[idx];
1217
    addr &= 0xFF0;
1218
    switch (addr) {
1219
    case 0x80: /* CTPR */
1220
        retval = dst->ctpr;
1221
        break;
1222
    case 0x90: /* WHOAMI */
1223
        retval = idx;
1224
        break;
1225
    case 0xA0: /* IACK */
1226
        retval = openpic_iack(opp, dst, idx);
1227
        break;
1228
    case 0xB0: /* EOI */
1229
        retval = 0;
1230
        break;
1231
    default:
1232
        break;
1233
    }
1234
    DPRINTF("%s: => 0x%08x\n", __func__, retval);
1235

    
1236
    return retval;
1237
}
1238

    
1239
static uint64_t openpic_cpu_read(void *opaque, hwaddr addr, unsigned len)
1240
{
1241
    return openpic_cpu_read_internal(opaque, addr, (addr & 0x1f000) >> 12);
1242
}
1243

    
1244
static const MemoryRegionOps openpic_glb_ops_le = {
1245
    .write = openpic_gbl_write,
1246
    .read  = openpic_gbl_read,
1247
    .endianness = DEVICE_LITTLE_ENDIAN,
1248
    .impl = {
1249
        .min_access_size = 4,
1250
        .max_access_size = 4,
1251
    },
1252
};
1253

    
1254
static const MemoryRegionOps openpic_glb_ops_be = {
1255
    .write = openpic_gbl_write,
1256
    .read  = openpic_gbl_read,
1257
    .endianness = DEVICE_BIG_ENDIAN,
1258
    .impl = {
1259
        .min_access_size = 4,
1260
        .max_access_size = 4,
1261
    },
1262
};
1263

    
1264
static const MemoryRegionOps openpic_tmr_ops_le = {
1265
    .write = openpic_tmr_write,
1266
    .read  = openpic_tmr_read,
1267
    .endianness = DEVICE_LITTLE_ENDIAN,
1268
    .impl = {
1269
        .min_access_size = 4,
1270
        .max_access_size = 4,
1271
    },
1272
};
1273

    
1274
static const MemoryRegionOps openpic_tmr_ops_be = {
1275
    .write = openpic_tmr_write,
1276
    .read  = openpic_tmr_read,
1277
    .endianness = DEVICE_BIG_ENDIAN,
1278
    .impl = {
1279
        .min_access_size = 4,
1280
        .max_access_size = 4,
1281
    },
1282
};
1283

    
1284
static const MemoryRegionOps openpic_cpu_ops_le = {
1285
    .write = openpic_cpu_write,
1286
    .read  = openpic_cpu_read,
1287
    .endianness = DEVICE_LITTLE_ENDIAN,
1288
    .impl = {
1289
        .min_access_size = 4,
1290
        .max_access_size = 4,
1291
    },
1292
};
1293

    
1294
static const MemoryRegionOps openpic_cpu_ops_be = {
1295
    .write = openpic_cpu_write,
1296
    .read  = openpic_cpu_read,
1297
    .endianness = DEVICE_BIG_ENDIAN,
1298
    .impl = {
1299
        .min_access_size = 4,
1300
        .max_access_size = 4,
1301
    },
1302
};
1303

    
1304
static const MemoryRegionOps openpic_src_ops_le = {
1305
    .write = openpic_src_write,
1306
    .read  = openpic_src_read,
1307
    .endianness = DEVICE_LITTLE_ENDIAN,
1308
    .impl = {
1309
        .min_access_size = 4,
1310
        .max_access_size = 4,
1311
    },
1312
};
1313

    
1314
static const MemoryRegionOps openpic_src_ops_be = {
1315
    .write = openpic_src_write,
1316
    .read  = openpic_src_read,
1317
    .endianness = DEVICE_BIG_ENDIAN,
1318
    .impl = {
1319
        .min_access_size = 4,
1320
        .max_access_size = 4,
1321
    },
1322
};
1323

    
1324
static const MemoryRegionOps openpic_msi_ops_be = {
1325
    .read = openpic_msi_read,
1326
    .write = openpic_msi_write,
1327
    .endianness = DEVICE_BIG_ENDIAN,
1328
    .impl = {
1329
        .min_access_size = 4,
1330
        .max_access_size = 4,
1331
    },
1332
};
1333

    
1334
static const MemoryRegionOps openpic_summary_ops_be = {
1335
    .read = openpic_summary_read,
1336
    .write = openpic_summary_write,
1337
    .endianness = DEVICE_BIG_ENDIAN,
1338
    .impl = {
1339
        .min_access_size = 4,
1340
        .max_access_size = 4,
1341
    },
1342
};
1343

    
1344
static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
1345
{
1346
    unsigned int i;
1347

    
1348
    for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
1349
        /* Always put the lower half of a 64-bit long first, in case we
1350
         * restore on a 32-bit host.  The least significant bits correspond
1351
         * to lower IRQ numbers in the bitmap.
1352
         */
1353
        qemu_put_be32(f, (uint32_t)q->queue[i]);
1354
#if LONG_MAX > 0x7FFFFFFF
1355
        qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32));
1356
#endif
1357
    }
1358

    
1359
    qemu_put_sbe32s(f, &q->next);
1360
    qemu_put_sbe32s(f, &q->priority);
1361
}
1362

    
1363
static void openpic_save(QEMUFile* f, void *opaque)
1364
{
1365
    OpenPICState *opp = (OpenPICState *)opaque;
1366
    unsigned int i;
1367

    
1368
    qemu_put_be32s(f, &opp->gcr);
1369
    qemu_put_be32s(f, &opp->vir);
1370
    qemu_put_be32s(f, &opp->pir);
1371
    qemu_put_be32s(f, &opp->spve);
1372
    qemu_put_be32s(f, &opp->tfrr);
1373

    
1374
    qemu_put_be32s(f, &opp->nb_cpus);
1375

    
1376
    for (i = 0; i < opp->nb_cpus; i++) {
1377
        qemu_put_sbe32s(f, &opp->dst[i].ctpr);
1378
        openpic_save_IRQ_queue(f, &opp->dst[i].raised);
1379
        openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
1380
        qemu_put_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
1381
                        sizeof(opp->dst[i].outputs_active));
1382
    }
1383

    
1384
    for (i = 0; i < MAX_TMR; i++) {
1385
        qemu_put_be32s(f, &opp->timers[i].tccr);
1386
        qemu_put_be32s(f, &opp->timers[i].tbcr);
1387
    }
1388

    
1389
    for (i = 0; i < opp->max_irq; i++) {
1390
        qemu_put_be32s(f, &opp->src[i].ivpr);
1391
        qemu_put_be32s(f, &opp->src[i].idr);
1392
        qemu_get_be32s(f, &opp->src[i].destmask);
1393
        qemu_put_sbe32s(f, &opp->src[i].last_cpu);
1394
        qemu_put_sbe32s(f, &opp->src[i].pending);
1395
    }
1396
}
1397

    
1398
static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
1399
{
1400
    unsigned int i;
1401

    
1402
    for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
1403
        unsigned long val;
1404

    
1405
        val = qemu_get_be32(f);
1406
#if LONG_MAX > 0x7FFFFFFF
1407
        val <<= 32;
1408
        val |= qemu_get_be32(f);
1409
#endif
1410

    
1411
        q->queue[i] = val;
1412
    }
1413

    
1414
    qemu_get_sbe32s(f, &q->next);
1415
    qemu_get_sbe32s(f, &q->priority);
1416
}
1417

    
1418
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
1419
{
1420
    OpenPICState *opp = (OpenPICState *)opaque;
1421
    unsigned int i;
1422

    
1423
    if (version_id != 1) {
1424
        return -EINVAL;
1425
    }
1426

    
1427
    qemu_get_be32s(f, &opp->gcr);
1428
    qemu_get_be32s(f, &opp->vir);
1429
    qemu_get_be32s(f, &opp->pir);
1430
    qemu_get_be32s(f, &opp->spve);
1431
    qemu_get_be32s(f, &opp->tfrr);
1432

    
1433
    qemu_get_be32s(f, &opp->nb_cpus);
1434

    
1435
    for (i = 0; i < opp->nb_cpus; i++) {
1436
        qemu_get_sbe32s(f, &opp->dst[i].ctpr);
1437
        openpic_load_IRQ_queue(f, &opp->dst[i].raised);
1438
        openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
1439
        qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
1440
                        sizeof(opp->dst[i].outputs_active));
1441
    }
1442

    
1443
    for (i = 0; i < MAX_TMR; i++) {
1444
        qemu_get_be32s(f, &opp->timers[i].tccr);
1445
        qemu_get_be32s(f, &opp->timers[i].tbcr);
1446
    }
1447

    
1448
    for (i = 0; i < opp->max_irq; i++) {
1449
        uint32_t val;
1450

    
1451
        val = qemu_get_be32(f);
1452
        write_IRQreg_idr(opp, i, val);
1453
        val = qemu_get_be32(f);
1454
        write_IRQreg_ivpr(opp, i, val);
1455

    
1456
        qemu_get_be32s(f, &opp->src[i].ivpr);
1457
        qemu_get_be32s(f, &opp->src[i].idr);
1458
        qemu_get_be32s(f, &opp->src[i].destmask);
1459
        qemu_get_sbe32s(f, &opp->src[i].last_cpu);
1460
        qemu_get_sbe32s(f, &opp->src[i].pending);
1461
    }
1462

    
1463
    return 0;
1464
}
1465

    
1466
typedef struct MemReg {
1467
    const char             *name;
1468
    MemoryRegionOps const  *ops;
1469
    hwaddr      start_addr;
1470
    ram_addr_t              size;
1471
} MemReg;
1472

    
1473
static void fsl_common_init(OpenPICState *opp)
1474
{
1475
    int i;
1476
    int virq = MAX_SRC;
1477

    
1478
    opp->vid = VID_REVISION_1_2;
1479
    opp->vir = VIR_GENERIC;
1480
    opp->vector_mask = 0xFFFF;
1481
    opp->tfrr_reset = 0;
1482
    opp->ivpr_reset = IVPR_MASK_MASK;
1483
    opp->idr_reset = 1 << 0;
1484
    opp->max_irq = MAX_IRQ;
1485

    
1486
    opp->irq_ipi0 = virq;
1487
    virq += MAX_IPI;
1488
    opp->irq_tim0 = virq;
1489
    virq += MAX_TMR;
1490

    
1491
    assert(virq <= MAX_IRQ);
1492

    
1493
    opp->irq_msi = 224;
1494

    
1495
    msi_supported = true;
1496
    for (i = 0; i < opp->fsl->max_ext; i++) {
1497
        opp->src[i].level = false;
1498
    }
1499

    
1500
    /* Internal interrupts, including message and MSI */
1501
    for (i = 16; i < MAX_SRC; i++) {
1502
        opp->src[i].type = IRQ_TYPE_FSLINT;
1503
        opp->src[i].level = true;
1504
    }
1505

    
1506
    /* timers and IPIs */
1507
    for (i = MAX_SRC; i < virq; i++) {
1508
        opp->src[i].type = IRQ_TYPE_FSLSPECIAL;
1509
        opp->src[i].level = false;
1510
    }
1511
}
1512

    
1513
static void map_list(OpenPICState *opp, const MemReg *list, int *count)
1514
{
1515
    while (list->name) {
1516
        assert(*count < ARRAY_SIZE(opp->sub_io_mem));
1517

    
1518
        memory_region_init_io(&opp->sub_io_mem[*count], list->ops, opp,
1519
                              list->name, list->size);
1520

    
1521
        memory_region_add_subregion(&opp->mem, list->start_addr,
1522
                                    &opp->sub_io_mem[*count]);
1523

    
1524
        (*count)++;
1525
        list++;
1526
    }
1527
}
1528

    
1529
static int openpic_init(SysBusDevice *dev)
1530
{
1531
    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);
1532
    int i, j;
1533
    int list_count = 0;
1534
    static const MemReg list_le[] = {
1535
        {"glb", &openpic_glb_ops_le,
1536
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1537
        {"tmr", &openpic_tmr_ops_le,
1538
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1539
        {"src", &openpic_src_ops_le,
1540
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1541
        {"cpu", &openpic_cpu_ops_le,
1542
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1543
        {NULL}
1544
    };
1545
    static const MemReg list_be[] = {
1546
        {"glb", &openpic_glb_ops_be,
1547
                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},
1548
        {"tmr", &openpic_tmr_ops_be,
1549
                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},
1550
        {"src", &openpic_src_ops_be,
1551
                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},
1552
        {"cpu", &openpic_cpu_ops_be,
1553
                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},
1554
        {NULL}
1555
    };
1556
    static const MemReg list_fsl[] = {
1557
        {"msi", &openpic_msi_ops_be,
1558
                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},
1559
        {"summary", &openpic_summary_ops_be,
1560
                OPENPIC_SUMMARY_REG_START, OPENPIC_SUMMARY_REG_SIZE},
1561
        {NULL}
1562
    };
1563

    
1564
    memory_region_init(&opp->mem, "openpic", 0x40000);
1565

    
1566
    switch (opp->model) {
1567
    case OPENPIC_MODEL_FSL_MPIC_20:
1568
    default:
1569
        opp->fsl = &fsl_mpic_20;
1570
        opp->brr1 = 0x00400200;
1571
        opp->flags |= OPENPIC_FLAG_IDR_CRIT;
1572
        opp->nb_irqs = 80;
1573
        opp->mpic_mode_mask = GCR_MODE_MIXED;
1574

    
1575
        fsl_common_init(opp);
1576
        map_list(opp, list_be, &list_count);
1577
        map_list(opp, list_fsl, &list_count);
1578

    
1579
        break;
1580

    
1581
    case OPENPIC_MODEL_FSL_MPIC_42:
1582
        opp->fsl = &fsl_mpic_42;
1583
        opp->brr1 = 0x00400402;
1584
        opp->flags |= OPENPIC_FLAG_ILR;
1585
        opp->nb_irqs = 196;
1586
        opp->mpic_mode_mask = GCR_MODE_PROXY;
1587

    
1588
        fsl_common_init(opp);
1589
        map_list(opp, list_be, &list_count);
1590
        map_list(opp, list_fsl, &list_count);
1591

    
1592
        break;
1593

    
1594
    case OPENPIC_MODEL_RAVEN:
1595
        opp->nb_irqs = RAVEN_MAX_EXT;
1596
        opp->vid = VID_REVISION_1_3;
1597
        opp->vir = VIR_GENERIC;
1598
        opp->vector_mask = 0xFF;
1599
        opp->tfrr_reset = 4160000;
1600
        opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;
1601
        opp->idr_reset = 0;
1602
        opp->max_irq = RAVEN_MAX_IRQ;
1603
        opp->irq_ipi0 = RAVEN_IPI_IRQ;
1604
        opp->irq_tim0 = RAVEN_TMR_IRQ;
1605
        opp->brr1 = -1;
1606
        opp->mpic_mode_mask = GCR_MODE_MIXED;
1607

    
1608
        /* Only UP supported today */
1609
        if (opp->nb_cpus != 1) {
1610
            return -EINVAL;
1611
        }
1612

    
1613
        map_list(opp, list_le, &list_count);
1614
        break;
1615
    }
1616

    
1617
    for (i = 0; i < opp->nb_cpus; i++) {
1618
        opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB);
1619
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
1620
            sysbus_init_irq(dev, &opp->dst[i].irqs[j]);
1621
        }
1622
    }
1623

    
1624
    register_savevm(&opp->busdev.qdev, "openpic", 0, 2,
1625
                    openpic_save, openpic_load, opp);
1626

    
1627
    sysbus_init_mmio(dev, &opp->mem);
1628
    qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq);
1629

    
1630
    return 0;
1631
}
1632

    
1633
static Property openpic_properties[] = {
1634
    DEFINE_PROP_UINT32("model", OpenPICState, model, OPENPIC_MODEL_FSL_MPIC_20),
1635
    DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1),
1636
    DEFINE_PROP_END_OF_LIST(),
1637
};
1638

    
1639
static void openpic_class_init(ObjectClass *klass, void *data)
1640
{
1641
    DeviceClass *dc = DEVICE_CLASS(klass);
1642
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1643

    
1644
    k->init = openpic_init;
1645
    dc->props = openpic_properties;
1646
    dc->reset = openpic_reset;
1647
}
1648

    
1649
static const TypeInfo openpic_info = {
1650
    .name          = "openpic",
1651
    .parent        = TYPE_SYS_BUS_DEVICE,
1652
    .instance_size = sizeof(OpenPICState),
1653
    .class_init    = openpic_class_init,
1654
};
1655

    
1656
static void openpic_register_types(void)
1657
{
1658
    type_register_static(&openpic_info);
1659
}
1660

    
1661
type_init(openpic_register_types)