Revision c988bfad

b/hw/arm_gic.c
48 48
} gic_irq_state;
49 49

  
50 50
#define ALL_CPU_MASK ((1 << NCPU) - 1)
51
#if NCPU > 1
52
#define NUM_CPU(s) ((s)->num_cpu)
53
#else
54
#define NUM_CPU(s) 1
55
#endif
51 56

  
52 57
#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
53 58
#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
......
95 100
    int running_priority[NCPU];
96 101
    int current_pending[NCPU];
97 102

  
103
#if NCPU > 1
104
    int num_cpu;
105
#endif
106

  
98 107
    int iomemtype;
99 108
} gic_state;
100 109

  
......
109 118
    int cpu;
110 119
    int cm;
111 120

  
112
    for (cpu = 0; cpu < NCPU; cpu++) {
121
    for (cpu = 0; cpu < NUM_CPU(s); cpu++) {
113 122
        cm = 1 << cpu;
114 123
        s->current_pending[cpu] = 1023;
115 124
        if (!s->enabled || !s->cpu_enabled[cpu]) {
......
255 264
        if (offset == 0)
256 265
            return s->enabled;
257 266
        if (offset == 4)
258
            return ((GIC_NIRQ / 32) - 1) | ((NCPU - 1) << 5);
267
            return ((GIC_NIRQ / 32) - 1) | ((NUM_CPU(s) - 1) << 5);
259 268
        if (offset < 0x08)
260 269
            return 0;
261 270
#endif
......
620 629
{
621 630
    int i;
622 631
    memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
623
    for (i = 0 ; i < NCPU; i++) {
632
    for (i = 0 ; i < NUM_CPU(s); i++) {
624 633
        s->priority_mask[i] = 0xf0;
625 634
        s->current_pending[i] = 1023;
626 635
        s->running_irq[i] = 1023;
......
651 660
    int j;
652 661

  
653 662
    qemu_put_be32(f, s->enabled);
654
    for (i = 0; i < NCPU; i++) {
663
    for (i = 0; i < NUM_CPU(s); i++) {
655 664
        qemu_put_be32(f, s->cpu_enabled[i]);
656 665
#ifndef NVIC
657 666
        qemu_put_be32(f, s->irq_target[i]);
......
688 697
        return -EINVAL;
689 698

  
690 699
    s->enabled = qemu_get_be32(f);
691
    for (i = 0; i < NCPU; i++) {
700
    for (i = 0; i < NUM_CPU(s); i++) {
692 701
        s->cpu_enabled[i] = qemu_get_be32(f);
693 702
#ifndef NVIC
694 703
        s->irq_target[i] = qemu_get_be32(f);
......
717 726
    return 0;
718 727
}
719 728

  
729
#if NCPU > 1
730
static void gic_init(gic_state *s, int num_cpu)
731
#else
720 732
static void gic_init(gic_state *s)
733
#endif
721 734
{
722 735
    int i;
723 736

  
737
#if NCPU > 1
738
    s->num_cpu = num_cpu;
739
#endif
724 740
    qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, GIC_NIRQ - 32);
725
    for (i = 0; i < NCPU; i++) {
741
    for (i = 0; i < NUM_CPU(s); i++) {
726 742
        sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
727 743
    }
728 744
    s->iomemtype = cpu_register_io_memory(gic_dist_readfn,
b/hw/mpcore.c
44 44
    uint32_t scu_control;
45 45
    int iomemtype;
46 46
    mpcore_timer_state timer[8];
47
    uint32_t num_cpu;
47 48
} mpcore_priv_state;
48 49

  
49 50
/* Per-CPU Timers.  */
......
166 167
        case 0x00: /* Control.  */
167 168
            return s->scu_control;
168 169
        case 0x04: /* Configuration.  */
169
            return 0xf3;
170
            id = ((1 << s->num_cpu) - 1) << 4;
171
            return id | (s->num_cpu - 1);
170 172
        case 0x08: /* CPU status.  */
171 173
            return 0;
172 174
        case 0x0c: /* Invalidate all.  */
......
180 182
            id = gic_get_current_cpu();
181 183
        } else {
182 184
            id = (offset - 0x200) >> 8;
185
            if (id >= s->num_cpu) {
186
                return 0;
187
            }
183 188
        }
184 189
        return gic_cpu_read(&s->gic, id, offset & 0xff);
185 190
    } else if (offset < 0xb00) {
......
188 193
            id = gic_get_current_cpu();
189 194
        } else {
190 195
            id = (offset - 0x700) >> 8;
196
            if (id >= s->num_cpu) {
197
                return 0;
198
            }
191 199
        }
192 200
        id <<= 1;
193 201
        if (offset & 0x20)
......
224 232
        } else {
225 233
            id = (offset - 0x200) >> 8;
226 234
        }
227
        gic_cpu_write(&s->gic, id, offset & 0xff, value);
235
        if (id < s->num_cpu) {
236
            gic_cpu_write(&s->gic, id, offset & 0xff, value);
237
        }
228 238
    } else if (offset < 0xb00) {
229 239
        /* Timers.  */
230 240
        if (offset < 0x700) {
......
232 242
        } else {
233 243
            id = (offset - 0x700) >> 8;
234 244
        }
235
        id <<= 1;
236
        if (offset & 0x20)
237
          id++;
238
        mpcore_timer_write(&s->timer[id], offset & 0xf, value);
245
        if (id < s->num_cpu) {
246
            id <<= 1;
247
            if (offset & 0x20)
248
              id++;
249
            mpcore_timer_write(&s->timer[id], offset & 0xf, value);
250
        }
239 251
        return;
240 252
    }
241 253
    return;
......
267 279
    mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
268 280
    int i;
269 281

  
270
    gic_init(&s->gic);
282
    gic_init(&s->gic, s->num_cpu);
271 283
    s->iomemtype = cpu_register_io_memory(mpcore_priv_readfn,
272 284
                                          mpcore_priv_writefn, s);
273 285
    sysbus_init_mmio_cb(dev, 0x2000, mpcore_priv_map);
274
    for (i = 0; i < 8; i++) {
286
    for (i = 0; i < s->num_cpu * 2; i++) {
275 287
        mpcore_timer_init(s, &s->timer[i], i);
276 288
    }
277 289
    return 0;
......
284 296
    SysBusDevice busdev;
285 297
    qemu_irq cpuic[32];
286 298
    qemu_irq rvic[4][64];
299
    uint32_t num_cpu;
287 300
} mpcore_rirq_state;
288 301

  
289 302
/* Map baseboard IRQs onto CPU IRQ lines.  */
......
315 328
    mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
316 329
    DeviceState *gic;
317 330
    DeviceState *priv;
331
    SysBusDevice *bus_priv;
318 332
    int n;
319 333
    int i;
320 334

  
321
    priv = sysbus_create_simple("arm11mpcore_priv", MPCORE_PRIV_BASE, NULL);
322
    sysbus_pass_irq(dev, sysbus_from_qdev(priv));
335
    priv = qdev_create(NULL, "arm11mpcore_priv");
336
    qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu);
337
    qdev_init_nofail(priv);
338
    bus_priv = sysbus_from_qdev(priv);
339
    sysbus_mmio_map(bus_priv, 0, MPCORE_PRIV_BASE);
340
    sysbus_pass_irq(dev, bus_priv);
323 341
    for (i = 0; i < 32; i++) {
324 342
        s->cpuic[i] = qdev_get_gpio_in(priv, i);
325 343
    }
......
335 353
    return 0;
336 354
}
337 355

  
356
static SysBusDeviceInfo mpcore_rirq_info = {
357
    .init = realview_mpcore_init,
358
    .qdev.name  = "realview_mpcore",
359
    .qdev.size  = sizeof(mpcore_rirq_state),
360
    .qdev.props = (Property[]) {
361
        DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1),
362
        DEFINE_PROP_END_OF_LIST(),
363
    }
364
};
365

  
366
static SysBusDeviceInfo mpcore_priv_info = {
367
    .init = mpcore_priv_init,
368
    .qdev.name  = "arm11mpcore_priv",
369
    .qdev.size  = sizeof(mpcore_priv_state),
370
    .qdev.props = (Property[]) {
371
        DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
372
        DEFINE_PROP_END_OF_LIST(),
373
    }
374
};
375

  
338 376
static void mpcore_register_devices(void)
339 377
{
340
    sysbus_register_dev("realview_mpcore", sizeof(mpcore_rirq_state),
341
                        realview_mpcore_init);
342
    sysbus_register_dev("arm11mpcore_priv", sizeof(mpcore_priv_state),
343
                        mpcore_priv_init);
378
    sysbus_register_withprop(&mpcore_rirq_info);
379
    sysbus_register_withprop(&mpcore_priv_info);
344 380
}
345 381

  
346 382
device_init(mpcore_register_devices)
b/hw/realview.c
35 35
  env->regs[15] = 0x80000000;
36 36
}
37 37

  
38
enum realview_board_type {
39
    BOARD_EB,
40
    BOARD_EB_MPCORE
41
};
42

  
38 43
static void realview_init(ram_addr_t ram_size,
39 44
                     const char *boot_device,
40 45
                     const char *kernel_filename, const char *kernel_cmdline,
41
                     const char *initrd_filename, const char *cpu_model)
46
                     const char *initrd_filename, const char *cpu_model,
47
                     enum realview_board_type board_type)
42 48
{
43
    CPUState *env;
49
    CPUState *env = NULL;
44 50
    ram_addr_t ram_offset;
45 51
    DeviceState *dev;
52
    SysBusDevice *busdev;
46 53
    qemu_irq *irqp;
47 54
    qemu_irq pic[64];
48 55
    PCIBus *pci_bus;
......
50 57
    int n;
51 58
    int done_smc = 0;
52 59
    qemu_irq cpu_irq[4];
53
    int ncpu;
60
    int is_mpcore = (board_type == BOARD_EB_MPCORE);
54 61
    uint32_t proc_id = 0;
55 62

  
56
    if (!cpu_model)
57
        cpu_model = "arm926";
58
    /* FIXME: obey smp_cpus.  */
59
    if (strcmp(cpu_model, "arm11mpcore") == 0) {
60
        ncpu = 4;
61
    } else {
62
        ncpu = 1;
63
    }
64

  
65
    for (n = 0; n < ncpu; n++) {
63
    for (n = 0; n < smp_cpus; n++) {
66 64
        env = cpu_init(cpu_model);
67 65
        if (!env) {
68 66
            fprintf(stderr, "Unable to find CPU definition\n");
......
91 89

  
92 90
    arm_sysctl_init(0x10000000, 0xc1400400, proc_id);
93 91

  
94
    if (ncpu == 1) {
95
        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
96
           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects
97
           GIC1 to be nIRQ and ignores all the others, so do that for now.  */
98
        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
92
    if (is_mpcore) {
93
        dev = qdev_create(NULL, "realview_mpcore");
94
        qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
95
        qdev_init_nofail(dev);
96
        busdev = sysbus_from_qdev(dev);
97
        for (n = 0; n < smp_cpus; n++) {
98
            sysbus_connect_irq(busdev, n, cpu_irq[n]);
99
        }
99 100
    } else {
100
        dev = sysbus_create_varargs("realview_mpcore", -1,
101
                                    cpu_irq[0], cpu_irq[1], cpu_irq[2],
102
                                    cpu_irq[3], NULL);
101
        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
103 102
    }
104 103
    for (n = 0; n < 64; n++) {
105 104
        pic[n] = qdev_get_gpio_in(dev, n);
......
210 209
    realview_binfo.kernel_filename = kernel_filename;
211 210
    realview_binfo.kernel_cmdline = kernel_cmdline;
212 211
    realview_binfo.initrd_filename = initrd_filename;
213
    realview_binfo.nb_cpus = ncpu;
212
    realview_binfo.nb_cpus = smp_cpus;
214 213
    arm_load_kernel(first_cpu, &realview_binfo);
215 214
}
216 215

  
217
static QEMUMachine realview_machine = {
218
    .name = "realview",
216
static void realview_eb_init(ram_addr_t ram_size,
217
                     const char *boot_device,
218
                     const char *kernel_filename, const char *kernel_cmdline,
219
                     const char *initrd_filename, const char *cpu_model)
220
{
221
    if (!cpu_model) {
222
        cpu_model = "arm926";
223
    }
224
    realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
225
                  initrd_filename, cpu_model, BOARD_EB);
226
}
227

  
228
static void realview_eb_mpcore_init(ram_addr_t ram_size,
229
                     const char *boot_device,
230
                     const char *kernel_filename, const char *kernel_cmdline,
231
                     const char *initrd_filename, const char *cpu_model)
232
{
233
    if (!cpu_model) {
234
        cpu_model = "arm11mpcore";
235
    }
236
    realview_init(ram_size, boot_device, kernel_filename, kernel_cmdline,
237
                  initrd_filename, cpu_model, BOARD_EB_MPCORE);
238
}
239

  
240
static QEMUMachine realview_eb_machine = {
241
    .name = "realview-eb",
219 242
    .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
220
    .init = realview_init,
243
    .init = realview_eb_init,
244
    .use_scsi = 1,
245
};
246

  
247
static QEMUMachine realview_eb_mpcore_machine = {
248
    .name = "realview-eb-mpcore",
249
    .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)",
250
    .init = realview_eb_mpcore_init,
221 251
    .use_scsi = 1,
252
    .max_cpus = 4,
222 253
};
223 254

  
224 255
static void realview_machine_init(void)
225 256
{
226
    qemu_register_machine(&realview_machine);
257
    qemu_register_machine(&realview_eb_machine);
258
    qemu_register_machine(&realview_eb_mpcore_machine);
227 259
}
228 260

  
229 261
machine_init(realview_machine_init);
b/qemu-doc.texi
1663 1663

  
1664 1664
@itemize @minus
1665 1665
@item
1666
ARM926E, ARM1136, ARM11MPCORE(x4) or Cortex-A8 CPU
1666
ARM926E, ARM1136, ARM11MPCORE or Cortex-A8 CPU
1667 1667
@item
1668 1668
ARM AMBA Generic/Distributed Interrupt Controller
1669 1669
@item

Also available in: Unified diff