Revision fe7e8758

b/hw/arm-misc.h
34 34
};
35 35
void arm_load_kernel(CPUState *env, struct arm_boot_info *info);
36 36

  
37
/* armv7m_nvic.c */
38

  
39 37
/* Multiplication factor to convert from system clock ticks to qemu timer
40 38
   ticks.  */
41 39
extern int system_clock_scale;
42
qemu_irq *armv7m_nvic_init(CPUState *env);
43 40

  
44 41
#endif /* !ARM_MISC_H */
b/hw/arm_gic.c
32 32
#define GIC_BASE_IRQ    0
33 33
#endif
34 34

  
35
#define FROM_SYSBUSGIC(type, dev) \
36
    DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
37

  
35 38
typedef struct gic_irq_state
36 39
{
37 40
    /* ??? The documentation seems to imply the enable bits are global, even
......
74 77

  
75 78
typedef struct gic_state
76 79
{
80
    SysBusDevice busdev;
77 81
    qemu_irq parent_irq[NCPU];
78 82
    int enabled;
79 83
    int cpu_enabled[NCPU];
......
91 95
    int running_priority[NCPU];
92 96
    int current_pending[NCPU];
93 97

  
94
    qemu_irq *in;
95
#ifdef NVIC
96
    void *nvic;
97
#endif
98
    int iomemtype;
98 99
} gic_state;
99 100

  
100 101
/* TODO: Many places that call this routine could be optimized.  */
......
363 364
    uint32_t addr;
364 365
    addr = offset;
365 366
    if (addr < 0x100 || addr > 0xd00)
366
        return nvic_readl(s->nvic, addr);
367
        return nvic_readl(s, addr);
367 368
#endif
368 369
    val = gic_dist_readw(opaque, offset);
369 370
    val |= gic_dist_readw(opaque, offset + 2) << 16;
......
523 524
    uint32_t addr;
524 525
    addr = offset;
525 526
    if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
526
        nvic_writel(s->nvic, addr, value);
527
        nvic_writel(s, addr, value);
527 528
        return;
528 529
    }
529 530
#endif
......
716 717
    return 0;
717 718
}
718 719

  
719
static gic_state *gic_init(uint32_t dist_base, qemu_irq *parent_irq)
720
static void gic_init(gic_state *s)
720 721
{
721
    gic_state *s;
722
    int iomemtype;
723 722
    int i;
724 723

  
725
    s = (gic_state *)qemu_mallocz(sizeof(gic_state));
726
    s->in = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
724
    qdev_init_irq_sink(&s->busdev.qdev, gic_set_irq, GIC_NIRQ - 32);
727 725
    for (i = 0; i < NCPU; i++) {
728
        s->parent_irq[i] = parent_irq[i];
726
        sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
729 727
    }
730
    iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
731
                                       gic_dist_writefn, s);
732
    cpu_register_physical_memory(dist_base, 0x00001000,
733
                                 iomemtype);
728
    s->iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
729
                                          gic_dist_writefn, s);
734 730
    gic_reset(s);
735 731
    register_savevm("arm_gic", -1, 1, gic_save, gic_load, s);
736
    return s;
737 732
}
b/hw/armv7m.c
7 7
 * This code is licenced under the GPL.
8 8
 */
9 9

  
10
#include "hw.h"
10
#include "sysbus.h"
11 11
#include "arm-misc.h"
12 12
#include "sysemu.h"
13 13

  
......
140 140
                      const char *kernel_filename, const char *cpu_model)
141 141
{
142 142
    CPUState *env;
143
    qemu_irq *pic;
143
    DeviceState *nvic;
144
    /* FIXME: make this local state.  */
145
    static qemu_irq pic[64];
146
    qemu_irq *cpu_pic;
144 147
    uint32_t pc;
145 148
    int image_size;
146 149
    uint64_t entry;
147 150
    uint64_t lowaddr;
151
    int i;
148 152

  
149 153
    flash_size *= 1024;
150 154
    sram_size *= 1024;
......
176 180
                                 qemu_ram_alloc(sram_size) | IO_MEM_RAM);
177 181
    armv7m_bitband_init();
178 182

  
179
    pic = armv7m_nvic_init(env);
183
    nvic = qdev_create(NULL, "armv7m_nvic");
184
    qdev_set_prop_ptr(nvic, "cpu", env);
185
    qdev_init(nvic);
186
    cpu_pic = arm_pic_init_cpu(env);
187
    sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
188
    for (i = 0; i < 64; i++) {
189
        pic[i] = qdev_get_irq_sink(nvic, i);
190
    }
180 191

  
181 192
    image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
182 193
    if (image_size < 0) {
b/hw/armv7m_nvic.c
10 10
 * NVIC.  Much of that is also implemented here.
11 11
 */
12 12

  
13
#include "hw.h"
13
#include "sysbus.h"
14 14
#include "qemu-timer.h"
15 15
#include "arm-misc.h"
16 16

  
......
33 33
#include "arm_gic.c"
34 34

  
35 35
typedef struct {
36
    gic_state gic;
36 37
    struct {
37 38
        uint32_t control;
38 39
        uint32_t reload;
39 40
        int64_t tick;
40 41
        QEMUTimer *timer;
41 42
    } systick;
42
    gic_state *gic;
43 43
} nvic_state;
44 44

  
45 45
/* qemu timers run at 1GHz.   We want something closer to 1MHz.  */
......
91 91
    nvic_state *s = (nvic_state *)opaque;
92 92
    if (irq >= 16)
93 93
        irq += 16;
94
    gic_set_pending_private(s->gic, 0, irq);
94
    gic_set_pending_private(&s->gic, 0, irq);
95 95
}
96 96

  
97 97
/* Make pending IRQ active.  */
......
100 100
    nvic_state *s = (nvic_state *)opaque;
101 101
    uint32_t irq;
102 102

  
103
    irq = gic_acknowledge_irq(s->gic, 0);
103
    irq = gic_acknowledge_irq(&s->gic, 0);
104 104
    if (irq == 1023)
105 105
        hw_error("Interrupt but no vector\n");
106 106
    if (irq >= 32)
......
113 113
    nvic_state *s = (nvic_state *)opaque;
114 114
    if (irq >= 16)
115 115
        irq += 16;
116
    gic_complete_irq(s->gic, 0, irq);
116
    gic_complete_irq(&s->gic, 0, irq);
117 117
}
118 118

  
119 119
static uint32_t nvic_readl(void *opaque, uint32_t offset)
......
153 153
        return cpu_single_env->cp15.c0_cpuid;
154 154
    case 0xd04: /* Interrypt Control State.  */
155 155
        /* VECTACTIVE */
156
        val = s->gic->running_irq[0];
156
        val = s->gic.running_irq[0];
157 157
        if (val == 1023) {
158 158
            val = 0;
159 159
        } else if (val >= 32) {
160 160
            val -= 16;
161 161
        }
162 162
        /* RETTOBASE */
163
        if (s->gic->running_irq[0] == 1023
164
                || s->gic->last_active[s->gic->running_irq[0]][0] == 1023) {
163
        if (s->gic.running_irq[0] == 1023
164
                || s->gic.last_active[s->gic.running_irq[0]][0] == 1023) {
165 165
            val |= (1 << 11);
166 166
        }
167 167
        /* VECTPENDING */
168
        if (s->gic->current_pending[0] != 1023)
169
            val |= (s->gic->current_pending[0] << 12);
168
        if (s->gic.current_pending[0] != 1023)
169
            val |= (s->gic.current_pending[0] << 12);
170 170
        /* ISRPENDING */
171 171
        for (irq = 32; irq < GIC_NIRQ; irq++) {
172
            if (s->gic->irq_state[irq].pending) {
172
            if (s->gic.irq_state[irq].pending) {
173 173
                val |= (1 << 22);
174 174
                break;
175 175
            }
176 176
        }
177 177
        /* PENDSTSET */
178
        if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending)
178
        if (s->gic.irq_state[ARMV7M_EXCP_SYSTICK].pending)
179 179
            val |= (1 << 26);
180 180
        /* PENDSVSET */
181
        if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending)
181
        if (s->gic.irq_state[ARMV7M_EXCP_PENDSV].pending)
182 182
            val |= (1 << 28);
183 183
        /* NMIPENDSET */
184
        if (s->gic->irq_state[ARMV7M_EXCP_NMI].pending)
184
        if (s->gic.irq_state[ARMV7M_EXCP_NMI].pending)
185 185
            val |= (1 << 31);
186 186
        return val;
187 187
    case 0xd08: /* Vector Table Offset.  */
......
197 197
    case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority.  */
198 198
        irq = offset - 0xd14;
199 199
        val = 0;
200
        val = s->gic->priority1[irq++][0];
201
        val = s->gic->priority1[irq++][0] << 8;
202
        val = s->gic->priority1[irq++][0] << 16;
203
        val = s->gic->priority1[irq][0] << 24;
200
        val = s->gic.priority1[irq++][0];
201
        val = s->gic.priority1[irq++][0] << 8;
202
        val = s->gic.priority1[irq++][0] << 16;
203
        val = s->gic.priority1[irq][0] << 24;
204 204
        return val;
205 205
    case 0xd24: /* System Handler Status.  */
206 206
        val = 0;
207
        if (s->gic->irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
208
        if (s->gic->irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
209
        if (s->gic->irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
210
        if (s->gic->irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
211
        if (s->gic->irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
212
        if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
213
        if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
214
        if (s->gic->irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
215
        if (s->gic->irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
216
        if (s->gic->irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
217
        if (s->gic->irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
218
        if (s->gic->irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
219
        if (s->gic->irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
220
        if (s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
207
        if (s->gic.irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
208
        if (s->gic.irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
209
        if (s->gic.irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
210
        if (s->gic.irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
211
        if (s->gic.irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
212
        if (s->gic.irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
213
        if (s->gic.irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
214
        if (s->gic.irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
215
        if (s->gic.irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
216
        if (s->gic.irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
217
        if (s->gic.irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
218
        if (s->gic.irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
219
        if (s->gic.irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
220
        if (s->gic.irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
221 221
        return val;
222 222
    case 0xd28: /* Configurable Fault Status.  */
223 223
        /* TODO: Implement Fault Status.  */
......
307 307
        if (value & (1 << 28)) {
308 308
            armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
309 309
        } else if (value & (1 << 27)) {
310
            s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
311
            gic_update(s->gic);
310
            s->gic.irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
311
            gic_update(&s->gic);
312 312
        }
313 313
        if (value & (1 << 26)) {
314 314
            armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
315 315
        } else if (value & (1 << 25)) {
316
            s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
317
            gic_update(s->gic);
316
            s->gic.irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
317
            gic_update(&s->gic);
318 318
        }
319 319
        break;
320 320
    case 0xd08: /* Vector Table Offset.  */
......
338 338
        {
339 339
            int irq;
340 340
            irq = offset - 0xd14;
341
            s->gic->priority1[irq++][0] = value & 0xff;
342
            s->gic->priority1[irq++][0] = (value >> 8) & 0xff;
343
            s->gic->priority1[irq++][0] = (value >> 16) & 0xff;
344
            s->gic->priority1[irq][0] = (value >> 24) & 0xff;
345
            gic_update(s->gic);
341
            s->gic.priority1[irq++][0] = value & 0xff;
342
            s->gic.priority1[irq++][0] = (value >> 8) & 0xff;
343
            s->gic.priority1[irq++][0] = (value >> 16) & 0xff;
344
            s->gic.priority1[irq][0] = (value >> 24) & 0xff;
345
            gic_update(&s->gic);
346 346
        }
347 347
        break;
348 348
    case 0xd24: /* System Handler Control.  */
349 349
        /* TODO: Real hardware allows you to set/clear the active bits
350 350
           under some circumstances.  We don't implement this.  */
351
        s->gic->irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
352
        s->gic->irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
353
        s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
351
        s->gic.irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
352
        s->gic.irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
353
        s->gic.irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
354 354
        break;
355 355
    case 0xd28: /* Configurable Fault Status.  */
356 356
    case 0xd2c: /* Hard Fault Status.  */
......
390 390
    return 0;
391 391
}
392 392

  
393
qemu_irq *armv7m_nvic_init(CPUState *env)
393
static void armv7m_nvic_init(SysBusDevice *dev)
394 394
{
395
    nvic_state *s;
396
    qemu_irq *parent;
395
    nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
396
    CPUState *env;
397 397

  
398
    parent = arm_pic_init_cpu(env);
399
    s = (nvic_state *)qemu_mallocz(sizeof(nvic_state));
400
    s->gic = gic_init(0xe000e000, &parent[ARM_PIC_CPU_IRQ]);
401
    s->gic->nvic = s;
398
    env = qdev_get_prop_ptr(&dev->qdev, "cpu");
399
    gic_init(&s->gic);
400
    cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
402 401
    s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s);
403 402
    if (env->v7m.nvic)
404 403
        hw_error("CPU can only have one NVIC\n");
405 404
    env->v7m.nvic = s;
406 405
    register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
407
    return s->gic->in;
408 406
}
407

  
408
static void armv7m_nvic_register_devices(void)
409
{
410
    sysbus_register_dev("armv7m_nvic", sizeof(nvic_state), armv7m_nvic_init);
411
}
412

  
413
device_init(armv7m_nvic_register_devices)
b/hw/mpcore.c
7 7
 * This code is licenced under the GPL.
8 8
 */
9 9

  
10
#include "hw.h"
10
#include "sysbus.h"
11 11
#include "qemu-timer.h"
12
#include "primecell.h"
13 12

  
14 13
#define MPCORE_PRIV_BASE  0x10100000
15 14
#define NCPU 4
......
41 40
} mpcore_timer_state;
42 41

  
43 42
typedef struct mpcore_priv_state {
44
    gic_state *gic;
43
    gic_state gic;
45 44
    uint32_t scu_control;
45
    int iomemtype;
46 46
    mpcore_timer_state timer[8];
47 47
} mpcore_priv_state;
48 48

  
......
51 51
static inline void mpcore_timer_update_irq(mpcore_timer_state *s)
52 52
{
53 53
    if (s->status & ~s->old_status) {
54
        gic_set_pending_private(s->mpcore->gic, s->id >> 1, 29 + (s->id & 1));
54
        gic_set_pending_private(&s->mpcore->gic, s->id >> 1, 29 + (s->id & 1));
55 55
    }
56 56
    s->old_status = s->status;
57 57
}
......
181 181
        } else {
182 182
            id = (offset - 0x200) >> 8;
183 183
        }
184
        return gic_cpu_read(s->gic, id, offset & 0xff);
184
        return gic_cpu_read(&s->gic, id, offset & 0xff);
185 185
    } else if (offset < 0xb00) {
186 186
        /* Timers.  */
187 187
        if (offset < 0x700) {
......
224 224
        } else {
225 225
            id = (offset - 0x200) >> 8;
226 226
        }
227
        gic_cpu_write(s->gic, id, offset & 0xff, value);
227
        gic_cpu_write(&s->gic, id, offset & 0xff, value);
228 228
    } else if (offset < 0xb00) {
229 229
        /* Timers.  */
230 230
        if (offset < 0x700) {
......
255 255
   mpcore_priv_write
256 256
};
257 257

  
258
static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
259
{
260
    mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
261
    cpu_register_physical_memory(base, 0x1000, s->iomemtype);
262
    cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
263
}
258 264

  
259
static qemu_irq *mpcore_priv_init(uint32_t base, qemu_irq *pic_irq)
265
static void mpcore_priv_init(SysBusDevice *dev)
260 266
{
261
    mpcore_priv_state *s;
262
    int iomemtype;
267
    mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
263 268
    int i;
264 269

  
265
    s = (mpcore_priv_state *)qemu_mallocz(sizeof(mpcore_priv_state));
266
    s->gic = gic_init(base + 0x1000, pic_irq);
267
    if (!s->gic)
268
        return NULL;
269
    iomemtype = cpu_register_io_memory(0, mpcore_priv_readfn,
270
                                       mpcore_priv_writefn, s);
271
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
270
    gic_init(&s->gic);
271
    s->iomemtype = cpu_register_io_memory(0, mpcore_priv_readfn,
272
                                          mpcore_priv_writefn, s);
273
    sysbus_init_mmio_cb(dev, 0x2000, mpcore_priv_map);
272 274
    for (i = 0; i < 8; i++) {
273 275
        mpcore_timer_init(s, &s->timer[i], i);
274 276
    }
275
    return s->gic->in;
276 277
}
277 278

  
278 279
/* Dummy PIC to route IRQ lines.  The baseboard has 4 independent IRQ
279 280
   controllers.  The output of these, plus some of the raw input lines
280 281
   are fed into a single SMP-aware interrupt controller on the CPU.  */
281 282
typedef struct {
282
    qemu_irq *cpuic;
283
    qemu_irq *rvic[4];
283
    SysBusDevice busdev;
284
    qemu_irq cpuic[32];
285
    qemu_irq rvic[4][64];
284 286
} mpcore_rirq_state;
285 287

  
286 288
/* Map baseboard IRQs onto CPU IRQ lines.  */
......
307 309
    }
308 310
}
309 311

  
310
qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq)
312
static void realview_mpcore_init(SysBusDevice *dev)
311 313
{
312
    mpcore_rirq_state *s;
314
    mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
315
    DeviceState *gic;
316
    DeviceState *priv;
313 317
    int n;
318
    int i;
314 319

  
320
    priv = sysbus_create_simple("arm11mpcore_priv", MPCORE_PRIV_BASE, NULL);
321
    sysbus_pass_irq(dev, sysbus_from_qdev(priv));
322
    for (i = 0; i < 32; i++) {
323
        s->cpuic[i] = qdev_get_irq_sink(priv, i);
324
    }
315 325
    /* ??? IRQ routing is hardcoded to "normal" mode.  */
316
    s = qemu_mallocz(sizeof(mpcore_rirq_state));
317
    s->cpuic = mpcore_priv_init(MPCORE_PRIV_BASE, cpu_irq);
318 326
    for (n = 0; n < 4; n++) {
319
        s->rvic[n] = realview_gic_init(0x10040000 + n * 0x10000,
320
                                       s->cpuic[10 + n]);
327
        gic = sysbus_create_simple("realview_gic", 0x10040000 + n * 0x10000,
328
                                   s->cpuic[10 + n]);
329
        for (i = 0; i < 64; i++) {
330
            s->rvic[n][i] = qdev_get_irq_sink(gic, i);
331
        }
321 332
    }
322
    return qemu_allocate_irqs(mpcore_rirq_set_irq, s, 64);
333
    qdev_init_irq_sink(&dev->qdev, mpcore_rirq_set_irq, 64);
323 334
}
335

  
336
static void mpcore_register_devices(void)
337
{
338
    sysbus_register_dev("realview_mpcore", sizeof(mpcore_rirq_state),
339
                        realview_mpcore_init);
340
    sysbus_register_dev("arm11mpcore_priv", sizeof(mpcore_priv_state),
341
                        mpcore_priv_init);
342
}
343

  
344
device_init(mpcore_register_devices)
b/hw/primecell.h
17 17
/* pl080.c */
18 18
void *pl080_init(uint32_t base, qemu_irq irq, int nchannels);
19 19

  
20
/* realview_gic.c */
21
qemu_irq *realview_gic_init(uint32_t base, qemu_irq parent_irq);
22

  
23
/* mpcore.c */
24
extern qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq);
25

  
26 20
/* arm_sysctl.c */
27 21
void arm_sysctl_init(uint32_t base, uint32_t sys_id);
28 22

  
b/hw/realview.c
31 31
{
32 32
    CPUState *env;
33 33
    ram_addr_t ram_offset;
34
    qemu_irq *pic;
35 34
    DeviceState *dev;
35
    qemu_irq *irqp;
36
    qemu_irq pic[64];
36 37
    PCIBus *pci_bus;
37 38
    NICInfo *nd;
38 39
    int n;
......
55 56
            fprintf(stderr, "Unable to find CPU definition\n");
56 57
            exit(1);
57 58
        }
58
        pic = arm_pic_init_cpu(env);
59
        cpu_irq[n] = pic[ARM_PIC_CPU_IRQ];
59
        irqp = arm_pic_init_cpu(env);
60
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
60 61
        if (n > 0) {
61 62
            /* Set entry point for secondary CPUs.  This assumes we're using
62 63
               the init code from arm_boot.c.  Real hardware resets all CPUs
......
76 77
        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
77 78
           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects
78 79
           GIC1 to be nIRQ and ignores all the others, so do that for now.  */
79
        pic = realview_gic_init(0x10040000, cpu_irq[0]);
80
        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
80 81
    } else {
81
        pic = mpcore_irq_init(cpu_irq);
82
        dev = sysbus_create_varargs("realview_mpcore", -1,
83
                                    cpu_irq[0], cpu_irq[1], cpu_irq[2],
84
                                    cpu_irq[3], NULL);
85
    }
86
    for (n = 0; n < 64; n++) {
87
        pic[n] = qdev_get_irq_sink(dev, n);
82 88
    }
83 89

  
84 90
    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
b/hw/realview_gic.c
7 7
 * This code is licenced under the GPL.
8 8
 */
9 9

  
10
#include "hw.h"
11
#include "primecell.h"
10
#include "sysbus.h"
12 11

  
13 12
#define GIC_NIRQ 96
14 13
#define NCPU 1
......
22 21

  
23 22
#include "arm_gic.c"
24 23

  
24
typedef struct {
25
    gic_state gic;
26
    int iomemtype;
27
} RealViewGICState;
28

  
25 29
static uint32_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset)
26 30
{
27 31
    gic_state *s = (gic_state *)opaque;
......
47 51
   realview_gic_cpu_write
48 52
};
49 53

  
50
qemu_irq *realview_gic_init(uint32_t base, qemu_irq parent_irq)
54
static void realview_gic_map(SysBusDevice *dev, target_phys_addr_t base)
51 55
{
52
    gic_state *s;
53
    int iomemtype;
56
    RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
57
    cpu_register_physical_memory(base, 0x1000, s->iomemtype);
58
    cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
59
}
60

  
61
static void realview_gic_init(SysBusDevice *dev)
62
{
63
    RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
54 64

  
55
    s = gic_init(base + 0x1000, &parent_irq);
56
    if (!s)
57
        return NULL;
58
    iomemtype = cpu_register_io_memory(0, realview_gic_cpu_readfn,
59
                                       realview_gic_cpu_writefn, s);
60
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
61
    return s->in;
65
    gic_init(&s->gic);
66
    s->iomemtype = cpu_register_io_memory(0, realview_gic_cpu_readfn,
67
                                          realview_gic_cpu_writefn, s);
68
    sysbus_init_mmio_cb(dev, 0x2000, realview_gic_map);
62 69
}
70

  
71
static void realview_gic_register_devices(void)
72
{
73
    sysbus_register_dev("realview_gic", sizeof(RealViewGICState),
74
                        realview_gic_init);
75
}
76

  
77
device_init(realview_gic_register_devices)

Also available in: Unified diff