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