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
234 static const int uartirq[] = {0, 2, 4, 18, 20};
235 qemu_irq txovrint = NULL, rxovrint = NULL;
236
237 if (i < 3) {
238 txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
239 rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
240 }
241
242 cmsdk_apb_uart_create(uartbase[i],
243 qdev_get_gpio_in(armv7m, uartirq[i] + 1),
244 qdev_get_gpio_in(armv7m, uartirq[i]),
245 txovrint, rxovrint,
246 NULL,
247 serial_hd(i), SYSCLK_FRQ);
248 }
249 break;
250 }
251 case FPGA_AN511:
252 {
253
254
255
256 Object *orgate;
257 DeviceState *orgate_dev;
258 int i;
259
260 orgate = object_new(TYPE_OR_IRQ);
261 object_property_set_int(orgate, 10, "num-lines", &error_fatal);
262 object_property_set_bool(orgate, true, "realized", &error_fatal);
263 orgate_dev = DEVICE(orgate);
264 qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
265
266 for (i = 0; i < 5; i++) {
267
268 static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
269 static const hwaddr uartbase[] = {0x40004000, 0x40005000,
270 0x4002c000, 0x4002d000,
271 0x4002e000};
272 Object *txrx_orgate;
273 DeviceState *txrx_orgate_dev;
274
275 txrx_orgate = object_new(TYPE_OR_IRQ);
276 object_property_set_int(txrx_orgate, 2, "num-lines", &error_fatal);
277 object_property_set_bool(txrx_orgate, true, "realized",
278 &error_fatal);
279 txrx_orgate_dev = DEVICE(txrx_orgate);
280 qdev_connect_gpio_out(txrx_orgate_dev, 0,
281 qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
282 cmsdk_apb_uart_create(uartbase[i],
283 qdev_get_gpio_in(txrx_orgate_dev, 0),
284 qdev_get_gpio_in(txrx_orgate_dev, 1),
285 qdev_get_gpio_in(orgate_dev, i * 2),
286 qdev_get_gpio_in(orgate_dev, i * 2 + 1),
287 NULL,
288 serial_hd(i), SYSCLK_FRQ);
289 }
290 break;
291 }
292 default:
293 g_assert_not_reached();
294 }
295
296 cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
297 cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
298
299 object_initialize(&mms->scc, sizeof(mms->scc), TYPE_MPS2_SCC);
300 sccdev = DEVICE(&mms->scc);
301 qdev_set_parent_bus(sccdev, sysbus_get_default());
302 qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
303 qdev_prop_set_uint32(sccdev, "scc-aid", 0x02000008);
304 qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
305 object_property_set_bool(OBJECT(&mms->scc), true, "realized",
306 &error_fatal);
307 sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
308
309
310
311
312 lan9118_init(&nd_table[0], 0x40200000,
313 qdev_get_gpio_in(armv7m,
314 mmc->fpga_type == FPGA_AN385 ? 13 : 47));
315
316 system_clock_scale = NANOSECONDS_PER_SECOND / SYSCLK_FRQ;
317
318 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
319 0x400000);
320}
321
322static void mps2_class_init(ObjectClass *oc, void *data)
323{
324 MachineClass *mc = MACHINE_CLASS(oc);
325
326 mc->init = mps2_common_init;
327 mc->max_cpus = 1;
328}
329
330static void mps2_an385_class_init(ObjectClass *oc, void *data)
331{
332 MachineClass *mc = MACHINE_CLASS(oc);
333 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
334
335 mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
336 mmc->fpga_type = FPGA_AN385;
337 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
338 mmc->scc_id = 0x41040000 | (385 << 4);
339}
340
341static void mps2_an511_class_init(ObjectClass *oc, void *data)
342{
343 MachineClass *mc = MACHINE_CLASS(oc);
344 MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
345
346 mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
347 mmc->fpga_type = FPGA_AN511;
348 mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
349 mmc->scc_id = 0x4104000 | (511 << 4);
350}
351
352static const TypeInfo mps2_info = {
353 .name = TYPE_MPS2_MACHINE,
354 .parent = TYPE_MACHINE,
355 .abstract = true,
356 .instance_size = sizeof(MPS2MachineState),
357 .class_size = sizeof(MPS2MachineClass),
358 .class_init = mps2_class_init,
359};
360
361static const TypeInfo mps2_an385_info = {
362 .name = TYPE_MPS2_AN385_MACHINE,
363 .parent = TYPE_MPS2_MACHINE,
364 .class_init = mps2_an385_class_init,
365};
366
367static const TypeInfo mps2_an511_info = {
368 .name = TYPE_MPS2_AN511_MACHINE,
369 .parent = TYPE_MPS2_MACHINE,
370 .class_init = mps2_an511_class_init,
371};
372
373static void mps2_machine_init(void)
374{
375 type_register_static(&mps2_info);
376 type_register_static(&mps2_an385_info);
377 type_register_static(&mps2_an511_info);
378}
379
380type_init(mps2_machine_init);
381