Revision 2206d2a6 hw/mpcore.c
b/hw/mpcore.c | ||
---|---|---|
41 | 41 |
{ |
42 | 42 |
mpcore_priv_state *s = (mpcore_priv_state *)opaque; |
43 | 43 |
int id; |
44 |
offset &= 0xfff;
|
|
44 |
offset &= 0xff; |
|
45 | 45 |
if (offset < 0x100) { |
46 | 46 |
/* SCU */ |
47 | 47 |
switch (offset) { |
... | ... | |
57 | 57 |
default: |
58 | 58 |
goto bad_reg; |
59 | 59 |
} |
60 |
} else if (offset < 0x600) { |
|
61 |
/* Interrupt controller. */ |
|
62 |
if (offset < 0x200) { |
|
63 |
id = gic_get_current_cpu(); |
|
64 |
} else { |
|
65 |
id = (offset - 0x200) >> 8; |
|
66 |
if (id >= s->num_cpu) { |
|
67 |
return 0; |
|
68 |
} |
|
69 |
} |
|
70 |
return gic_cpu_read(&s->gic, id, offset & 0xff); |
|
71 | 60 |
} |
72 | 61 |
bad_reg: |
73 | 62 |
hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset); |
... | ... | |
78 | 67 |
uint64_t value, unsigned size) |
79 | 68 |
{ |
80 | 69 |
mpcore_priv_state *s = (mpcore_priv_state *)opaque; |
81 |
int id; |
|
82 |
offset &= 0xfff; |
|
70 |
offset &= 0xff; |
|
83 | 71 |
if (offset < 0x100) { |
84 | 72 |
/* SCU */ |
85 | 73 |
switch (offset) { |
... | ... | |
92 | 80 |
default: |
93 | 81 |
goto bad_reg; |
94 | 82 |
} |
95 |
} else if (offset < 0x600) { |
|
96 |
/* Interrupt controller. */ |
|
97 |
if (offset < 0x200) { |
|
98 |
id = gic_get_current_cpu(); |
|
99 |
} else { |
|
100 |
id = (offset - 0x200) >> 8; |
|
101 |
} |
|
102 |
if (id < s->num_cpu) { |
|
103 |
gic_cpu_write(&s->gic, id, offset & 0xff, value); |
|
104 |
} |
|
105 | 83 |
} |
106 | 84 |
return; |
107 | 85 |
bad_reg: |
... | ... | |
129 | 107 |
SysBusDevice *busdev = sysbus_from_qdev(s->mptimer); |
130 | 108 |
memory_region_init(&s->container, "mpcode-priv-container", 0x2000); |
131 | 109 |
memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv", |
132 |
0x1000);
|
|
110 |
0x100); |
|
133 | 111 |
memory_region_add_subregion(&s->container, 0, &s->iomem); |
112 |
/* GIC CPU interfaces: "current CPU" at 0x100, then specific CPUs |
|
113 |
* at 0x200, 0x300... |
|
114 |
*/ |
|
115 |
for (i = 0; i < (s->num_cpu + 1); i++) { |
|
116 |
target_phys_addr_t offset = 0x100 + (i * 0x100); |
|
117 |
memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]); |
|
118 |
} |
|
134 | 119 |
/* Add the regions for timer and watchdog for "current CPU" and |
135 | 120 |
* for each specific CPU. |
136 | 121 |
*/ |
Also available in: Unified diff