1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "qapi/error.h"
27#include "qemu/error-report.h"
28#include "hw/arm/arm.h"
29#include "hw/arm/armv7m.h"
30#include "hw/or-irq.h"
31#include "hw/boards.h"
32#include "exec/address-spaces.h"
33#include "sysemu/sysemu.h"
34#include "hw/misc/unimp.h"
35#include "hw/char/cmsdk-apb-uart.h"
36#include "hw/timer/cmsdk-apb-timer.h"
37#include "hw/misc/mps2-scc.h"
38#include "hw/devices.h"
39#include "net/net.h"
40
41typedef enum MPS2FPGAType {
42 FPGA_AN385,
43 FPGA_AN511,
44} MPS2FPGAType;
45
46typedef struct {
47 MachineClass parent;
48 MPS2FPGAType fpga_type;
49 uint32_t scc_id;
50} MPS2MachineClass;
51
52typedef struct {
53 MachineState parent;
54
55 ARMv7MState armv7m;
56 MemoryRegion psram;
57 MemoryRegion ssram1;
58 MemoryRegion ssram1_m;
59 MemoryRegion ssram23;
60 MemoryRegion ssram23_m;
61 MemoryRegion blockram;
62 MemoryRegion blockram_m1;
63 MemoryRegion blockram_m2;
64 MemoryRegion blockram_m3;
65 MemoryRegion sram;
66 MPS2SCC scc;
67} MPS2MachineState;
68
69#define TYPE_MPS2_MACHINE "mps2"
70#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
71#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
72
73#define MPS2_MACHINE(obj) \
74 OBJECT_CHECK(MPS2MachineState, obj, TYPE_MPS2_MACHINE)
75#define MPS2_MACHINE_GET_CLASS(obj) \
76 OBJECT_GET_CLASS(MPS2MachineClass, obj, TYPE_MPS2_MACHINE)
77#define MPS2_MACHINE_CLASS(klass) \
78 OBJECT_CLASS_CHECK(MPS2MachineClass, klass, TYPE_MPS2_MACHINE)
79
80
81#define SYSCLK_FRQ 25000000
82
83
84
85
86static void make_ram(MemoryRegion *mr, const char *name,
87 hwaddr base, hwaddr size)
88{
89 memory_region_init_ram(mr, NULL, name, size, &error_fatal);
90 memory_region_add_subregion(get_system_memory(), base, mr);
91}
92
93
94
95
96static void make_ram_alias(MemoryRegion *mr, const char *name,
97 MemoryRegion *orig, hwaddr base)
98{
99 memory_region_init_alias(mr, NULL, name, orig, 0,
100 memory_region_size(orig));
101 memory_region_add_subregion(get_system_memory(), base, mr);
102}
103
104static void mps2_common_init(MachineState *machine)
105{
106 MPS2MachineState *mms = MPS2_MACHINE(machine);
107 MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
108 MemoryRegion *system_memory = get_system_memory();
109 MachineClass *mc = MACHINE_GET_CLASS(machine);
110 DeviceState *armv7m, *sccdev;
111
112 if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
113 error_report("This board can only be used with CPU %s",
114 mc->default_cpu_type);
115 exit(1);
116 }
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 memory_region_allocate_system_memory(&mms->psram,
147 NULL, "mps.ram", 0x1000000);
148 memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);
149
150 switch (mmc->fpga_type) {
151 case FPGA_AN385:
152 make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
153 make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
154 make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
155 make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
156 &mms->ssram23, 0x20400000);
157 make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
158 make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
159 &mms->blockram, 0x01004000);
160 make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
161 &mms->blockram, 0x01008000);
162 make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
163 &mms->blockram, 0x0100c000);
164 break;
165 case FPGA_AN511:
166 make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
167 make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
168 make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
169 make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
170 break;
171 default:
172 g_assert_not_reached();
173 }
174
175 object_initialize(&mms->armv7m, sizeof(mms->armv7m), TYPE_ARMV7M);
176 armv7m = DEVICE(&mms->armv7m);
177 qdev_set_parent_bus(armv7m, sysbus_get_default());
178 switch (mmc->fpga_type) {
179 case FPGA_AN385:
180 qdev_prop_set_uint32(armv7m, "num-irq", 32);
181 break;
182 case FPGA_AN511:
183 qdev_prop_set_uint32(armv7m, "num-irq", 64);
184 break;
185 default:
186 g_assert_not_reached();
187 }
188 qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
189 object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
190 "memory", &error_abort);
191 object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
192 &error_fatal);
193
194 create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
195 create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
196 create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
197 create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
198 create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
199 create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
200
201
202
203
204 create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
205 0x40000000, 0x00010000);
206 create_unimplemented_device("CMSDK peripheral region @0x40010000",
207 0x40010000, 0x00010000);
208 create_unimplemented_device("Extra peripheral region @0x40020000",
209 0x40020000, 0x00010000);
210 create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
211 create_unimplemented_device("VGA", 0x41000000, 0x0200000);
212
213 switch (mmc->fpga_type) {
214 case FPGA_AN385:
215 {
216
217
218
219 Object *orgate;
220 DeviceState *orgate_dev;
221 int i;
222
223 orgate = object_new(TYPE_OR_IRQ);
224 object_property_set_int(orgate, 6, "num-lines", &error_fatal);
225 object_property_set_bool(orgate, true, "realized", &error_fatal);
226 orgate_dev = DEVICE(orgate);
227 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
228
229 for (i = 0; i < 5; i++) {
230 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
231 0x40006000, 0x40007000,
232 0x40009000};
233 Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
234
235 static const int uartirq[] = {0, 2, 4, 18, 20};
236 qemu_irq txovrint = NULL, rxovrint = NULL;
237
238 if (i < 3) {
239 txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
240 rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
241 }
242
243 cmsdk_apb_uart_create(uartbase[i],
244 qdev_get_gpio_in(armv7m, uartirq[i] + 1),
245 qdev_get_gpio_in(armv7m, uartirq[i]),
246 txovrint, rxovrint,
247 NULL,
248 uartchr, SYSCLK_FRQ);
249 }
250 break;
251 }
252 case FPGA_AN511:
253 {
254
255
256
257 Object *orgate;
258 DeviceState *orgate_dev;
259 int i;
260
261 orgate = object_new(TYPE_OR_IRQ);
262 object_property_set_int(orgate, 10, "num-lines", &error_fatal);
263 object_property_set_bool(orgate, true, "realized", &error_fatal);
264 orgate_dev = DEVICE(orgate);
265 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
266
267 for (i = 0; i < 5; i++) {
268
269 static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
270 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
271 0x4002c000, 0x4002d000,
272 0x4002e000};
273 Chardev *uartchr = i < MAX_SERIAL_PORTS ? serial_hds[i] : NULL;
274 Object *txrx_orgate;
275 DeviceState *txrx_orgate_dev;
276
277 txrx_orgate = object_new(TYPE_OR_IRQ);
278 object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
279 object_property_set_bool(txrx_orgate, true, "realized",
280 &error_fatal);
281 txrx_orgate_dev = DEVICE(txrx_orgate);
282 qdev_connect_gpio_out(txrx_orgate_dev, 0,
283 qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
284 cmsdk_apb_uart_create(uartbase[i],
285 qdev_get_gpio_in(txrx_orgate_dev, 0),
286 qdev_get_gpio_in(txrx_orgate_dev, 1),
287 qdev_get_gpio_in(orgate_dev, i * 2),
288 qdev_get_gpio_in(orgate_dev, i * 2 + 1),
289 NULL,
290 uartchr, SYSCLK_FRQ);
291 }
292 break;
293 }
294 default:
295 g_assert_not_reached();
296 }
297
298 cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
299 cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
300
301 object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
302 sccdev = DEVICE(&mms->scc);
303 qdev_set_parent_bus(sccdev, sysbus_get_default());
304 qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
305 qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
306 qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
307 object_property_set_bool(OBJECT(&mms->scc), true, "realized",
308 &error_fatal);
309 sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
310
311
312
313
314 lan9118_init(&nd_table[0], 0x40200000,
315 qdev_get_gpio_in(armv7m,
316 mmc->fpga_type == FPGA_AN385 ? 13 : 47));
317
318 system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
319
320 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
321 0x400000);
322}
323
324static void mps2_class_init(ObjectClass *oc, void *data)
325{
326 MachineClass *mc = MACHINE_CLASS(oc);
327
328 mc->init = mps2_common_init;
329 mc->max_cpus = 1;
330}
331
332static void mps2_an385_class_init(ObjectClass *oc, void *data)
333{
334 MachineClass *mc = MACHINE_CLASS(oc);
335 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
336
337 mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
338 mmc->fpga_type = FPGA_AN385;
339 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
340 mmc->scc_id = 0x41040000 | (385 << 4);
341}
342
343static void mps2_an511_class_init(ObjectClass *oc, void *data)
344{
345 MachineClass *mc = MACHINE_CLASS(oc);
346 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
347
348 mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
349 mmc->fpga_type = FPGA_AN511;
350 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
351 mmc->scc_id = 0x4104000 | (511 << 4);
352}
353
354static const TypeInfo mps2_info = {
355 .name = TYPE_MPS2_MACHINE,
356 .parent = TYPE_MACHINE,
357 .abstract = true,
358 .instance_size = sizeof(MPS2MachineState),
359 .class_size = sizeof(MPS2MachineClass),
360 .class_init = mps2_class_init,
361};
362
363static const TypeInfo mps2_an385_info = {
364 .name = TYPE_MPS2_AN385_MACHINE,
365 .parent = TYPE_MPS2_MACHINE,
366 .class_init = mps2_an385_class_init,
367};
368
369static const TypeInfo mps2_an511_info = {
370 .name = TYPE_MPS2_AN511_MACHINE,
371 .parent = TYPE_MPS2_MACHINE,
372 .class_init = mps2_an511_class_init,
373};
374
375static void mps2_machine_init(void)
376{
377 type_register_static(&mps2_info);
378 type_register_static(&mps2_an385_info);
379 type_register_static(&mps2_an511_info);
380}
381
382type_init(mps2_machine_init);
383