root / hw / arm11mpcore.c @ da726e5e
History | View | Annotate | Download (3.1 kB)
1 | f7c70325 | Paul Brook | /*
|
---|---|---|---|
2 | f7c70325 | Paul Brook | * ARM11MPCore internal peripheral emulation.
|
3 | f7c70325 | Paul Brook | *
|
4 | f7c70325 | Paul Brook | * Copyright (c) 2006-2007 CodeSourcery.
|
5 | f7c70325 | Paul Brook | * Written by Paul Brook
|
6 | f7c70325 | Paul Brook | *
|
7 | 8e31bf38 | Matthew Fernandez | * This code is licensed under the GPL.
|
8 | f7c70325 | Paul Brook | */
|
9 | f7c70325 | Paul Brook | |
10 | f7c70325 | Paul Brook | /* ??? The MPCore TRM says the on-chip controller has 224 external IRQ lines
|
11 | f7c70325 | Paul Brook | (+ 32 internal). However my test chip only exposes/reports 32.
|
12 | f7c70325 | Paul Brook | More importantly Linux falls over if more than 32 are present! */
|
13 | f7c70325 | Paul Brook | #define GIC_NIRQ 64 |
14 | f7c70325 | Paul Brook | #include "mpcore.c" |
15 | f7c70325 | Paul Brook | |
16 | f7c70325 | Paul Brook | /* Dummy PIC to route IRQ lines. The baseboard has 4 independent IRQ
|
17 | f7c70325 | Paul Brook | controllers. The output of these, plus some of the raw input lines
|
18 | f7c70325 | Paul Brook | are fed into a single SMP-aware interrupt controller on the CPU. */
|
19 | f7c70325 | Paul Brook | typedef struct { |
20 | f7c70325 | Paul Brook | SysBusDevice busdev; |
21 | f7c70325 | Paul Brook | SysBusDevice *priv; |
22 | f7c70325 | Paul Brook | qemu_irq cpuic[32];
|
23 | f7c70325 | Paul Brook | qemu_irq rvic[4][64]; |
24 | f7c70325 | Paul Brook | uint32_t num_cpu; |
25 | f7c70325 | Paul Brook | } mpcore_rirq_state; |
26 | f7c70325 | Paul Brook | |
27 | f7c70325 | Paul Brook | /* Map baseboard IRQs onto CPU IRQ lines. */
|
28 | f7c70325 | Paul Brook | static const int mpcore_irq_map[32] = { |
29 | f7c70325 | Paul Brook | -1, -1, -1, -1, 1, 2, -1, -1, |
30 | f7c70325 | Paul Brook | -1, -1, 6, -1, 4, 5, -1, -1, |
31 | f7c70325 | Paul Brook | -1, 14, 15, 0, 7, 8, -1, -1, |
32 | f7c70325 | Paul Brook | -1, -1, -1, -1, 9, 3, -1, -1, |
33 | f7c70325 | Paul Brook | }; |
34 | f7c70325 | Paul Brook | |
35 | f7c70325 | Paul Brook | static void mpcore_rirq_set_irq(void *opaque, int irq, int level) |
36 | f7c70325 | Paul Brook | { |
37 | f7c70325 | Paul Brook | mpcore_rirq_state *s = (mpcore_rirq_state *)opaque; |
38 | f7c70325 | Paul Brook | int i;
|
39 | f7c70325 | Paul Brook | |
40 | f7c70325 | Paul Brook | for (i = 0; i < 4; i++) { |
41 | f7c70325 | Paul Brook | qemu_set_irq(s->rvic[i][irq], level); |
42 | f7c70325 | Paul Brook | } |
43 | f7c70325 | Paul Brook | if (irq < 32) { |
44 | f7c70325 | Paul Brook | irq = mpcore_irq_map[irq]; |
45 | f7c70325 | Paul Brook | if (irq >= 0) { |
46 | f7c70325 | Paul Brook | qemu_set_irq(s->cpuic[irq], level); |
47 | f7c70325 | Paul Brook | } |
48 | f7c70325 | Paul Brook | } |
49 | f7c70325 | Paul Brook | } |
50 | f7c70325 | Paul Brook | |
51 | f7c70325 | Paul Brook | static int realview_mpcore_init(SysBusDevice *dev) |
52 | f7c70325 | Paul Brook | { |
53 | f7c70325 | Paul Brook | mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev); |
54 | f7c70325 | Paul Brook | DeviceState *gic; |
55 | f7c70325 | Paul Brook | DeviceState *priv; |
56 | f7c70325 | Paul Brook | int n;
|
57 | f7c70325 | Paul Brook | int i;
|
58 | f7c70325 | Paul Brook | |
59 | f7c70325 | Paul Brook | priv = qdev_create(NULL, "arm11mpcore_priv"); |
60 | f7c70325 | Paul Brook | qdev_prop_set_uint32(priv, "num-cpu", s->num_cpu);
|
61 | f7c70325 | Paul Brook | qdev_init_nofail(priv); |
62 | f7c70325 | Paul Brook | s->priv = sysbus_from_qdev(priv); |
63 | f7c70325 | Paul Brook | sysbus_pass_irq(dev, s->priv); |
64 | f7c70325 | Paul Brook | for (i = 0; i < 32; i++) { |
65 | f7c70325 | Paul Brook | s->cpuic[i] = qdev_get_gpio_in(priv, i); |
66 | f7c70325 | Paul Brook | } |
67 | f7c70325 | Paul Brook | /* ??? IRQ routing is hardcoded to "normal" mode. */
|
68 | f7c70325 | Paul Brook | for (n = 0; n < 4; n++) { |
69 | f7c70325 | Paul Brook | gic = sysbus_create_simple("realview_gic", 0x10040000 + n * 0x10000, |
70 | f7c70325 | Paul Brook | s->cpuic[10 + n]);
|
71 | f7c70325 | Paul Brook | for (i = 0; i < 64; i++) { |
72 | f7c70325 | Paul Brook | s->rvic[n][i] = qdev_get_gpio_in(gic, i); |
73 | f7c70325 | Paul Brook | } |
74 | f7c70325 | Paul Brook | } |
75 | f7c70325 | Paul Brook | qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
|
76 | dd236a50 | Peter Maydell | sysbus_init_mmio_region(dev, sysbus_mmio_get_region(s->priv, 0));
|
77 | f7c70325 | Paul Brook | return 0; |
78 | f7c70325 | Paul Brook | } |
79 | f7c70325 | Paul Brook | |
80 | f7c70325 | Paul Brook | static SysBusDeviceInfo mpcore_rirq_info = {
|
81 | f7c70325 | Paul Brook | .init = realview_mpcore_init, |
82 | f7c70325 | Paul Brook | .qdev.name = "realview_mpcore",
|
83 | f7c70325 | Paul Brook | .qdev.size = sizeof(mpcore_rirq_state),
|
84 | f7c70325 | Paul Brook | .qdev.props = (Property[]) { |
85 | f7c70325 | Paul Brook | DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1), |
86 | f7c70325 | Paul Brook | DEFINE_PROP_END_OF_LIST(), |
87 | f7c70325 | Paul Brook | } |
88 | f7c70325 | Paul Brook | }; |
89 | f7c70325 | Paul Brook | |
90 | f7c70325 | Paul Brook | static SysBusDeviceInfo mpcore_priv_info = {
|
91 | f7c70325 | Paul Brook | .init = mpcore_priv_init, |
92 | f7c70325 | Paul Brook | .qdev.name = "arm11mpcore_priv",
|
93 | f7c70325 | Paul Brook | .qdev.size = sizeof(mpcore_priv_state),
|
94 | f7c70325 | Paul Brook | .qdev.props = (Property[]) { |
95 | f7c70325 | Paul Brook | DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1), |
96 | f7c70325 | Paul Brook | DEFINE_PROP_END_OF_LIST(), |
97 | f7c70325 | Paul Brook | } |
98 | f7c70325 | Paul Brook | }; |
99 | f7c70325 | Paul Brook | |
100 | f7c70325 | Paul Brook | static void arm11mpcore_register_devices(void) |
101 | f7c70325 | Paul Brook | { |
102 | f7c70325 | Paul Brook | sysbus_register_withprop(&mpcore_rirq_info); |
103 | f7c70325 | Paul Brook | sysbus_register_withprop(&mpcore_priv_info); |
104 | f7c70325 | Paul Brook | } |
105 | f7c70325 | Paul Brook | |
106 | f7c70325 | Paul Brook | device_init(arm11mpcore_register_devices) |