1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "hw/arm/armv7m.h"
12#include "qapi/error.h"
13#include "hw/sysbus.h"
14#include "hw/arm/boot.h"
15#include "hw/loader.h"
16#include "hw/qdev-properties.h"
17#include "hw/qdev-clock.h"
18#include "elf.h"
19#include "sysemu/reset.h"
20#include "qemu/error-report.h"
21#include "qemu/module.h"
22#include "qemu/log.h"
23#include "target/arm/idau.h"
24#include "migration/vmstate.h"
25
26
27
28
29static inline hwaddr bitband_addr(BitBandState *s, hwaddr offset)
30{
31 return s->base | (offset & 0x1ffffff) >> 5;
32}
33
34static MemTxResult bitband_read(void *opaque, hwaddr offset,
35 uint64_t *data, unsigned size, MemTxAttrs attrs)
36{
37 BitBandState *s = opaque;
38 uint8_t buf[4];
39 MemTxResult res;
40 int bitpos, bit;
41 hwaddr addr;
42
43 assert(size <= 4);
44
45
46 addr = bitband_addr(s, offset) & (-size);
47 res = address_space_read(&s->source_as, addr, attrs, buf, size);
48 if (res) {
49 return res;
50 }
51
52 bitpos = (offset >> 2) & ((size * 8) - 1);
53
54 bit = (buf[bitpos >> 3] >> (bitpos & 7)) & 1;
55 *data = bit;
56 return MEMTX_OK;
57}
58
59static MemTxResult bitband_write(void *opaque, hwaddr offset, uint64_t value,
60 unsigned size, MemTxAttrs attrs)
61{
62 BitBandState *s = opaque;
63 uint8_t buf[4];
64 MemTxResult res;
65 int bitpos, bit;
66 hwaddr addr;
67
68 assert(size <= 4);
69
70
71 addr = bitband_addr(s, offset) & (-size);
72 res = address_space_read(&s->source_as, addr, attrs, buf, size);
73 if (res) {
74 return res;
75 }
76
77 bitpos = (offset >> 2) & ((size * 8) - 1);
78
79 bit = 1 << (bitpos & 7);
80 if (value & 1) {
81 buf[bitpos >> 3] |= bit;
82 } else {
83 buf[bitpos >> 3] &= ~bit;
84 }
85 return address_space_write(&s->source_as, addr, attrs, buf, size);
86}
87
88static const MemoryRegionOps bitband_ops = {
89 .read_with_attrs = bitband_read,
90 .write_with_attrs = bitband_write,
91 .endianness = DEVICE_NATIVE_ENDIAN,
92 .impl.min_access_size = 1,
93 .impl.max_access_size = 4,
94 .valid.min_access_size = 1,
95 .valid.max_access_size = 4,
96};
97
98static void bitband_init(Object *obj)
99{
100 BitBandState *s = BITBAND(obj);
101 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
102
103 memory_region_init_io(&s->iomem, obj, &bitband_ops, s,
104 "bitband", 0x02000000);
105 sysbus_init_mmio(dev, &s->iomem);
106}
107
108static void bitband_realize(DeviceState *dev, Error **errp)
109{
110 BitBandState *s = BITBAND(dev);
111
112 if (!s->source_memory) {
113 error_setg(errp, "source-memory property not set");
114 return;
115 }
116
117 address_space_init(&s->source_as, s->source_memory, "bitband-source");
118}
119
120
121
122static const hwaddr bitband_input_addr[ARMV7M_NUM_BITBANDS] = {
123 0x20000000, 0x40000000
124};
125
126static const hwaddr bitband_output_addr[ARMV7M_NUM_BITBANDS] = {
127 0x22000000, 0x42000000
128};
129
130static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
131 uint64_t value, unsigned size,
132 MemTxAttrs attrs)
133{
134 MemoryRegion *mr = opaque;
135
136 if (attrs.secure) {
137
138 attrs.secure = 0;
139 return memory_region_dispatch_write(mr, addr, value,
140 size_memop(size) | MO_TE, attrs);
141 } else {
142
143 if (attrs.user) {
144 return MEMTX_ERROR;
145 }
146 return MEMTX_OK;
147 }
148}
149
150static MemTxResult v7m_sysreg_ns_read(void *opaque, hwaddr addr,
151 uint64_t *data, unsigned size,
152 MemTxAttrs attrs)
153{
154 MemoryRegion *mr = opaque;
155
156 if (attrs.secure) {
157
158 attrs.secure = 0;
159 return memory_region_dispatch_read(mr, addr, data,
160 size_memop(size) | MO_TE, attrs);
161 } else {
162
163 if (attrs.user) {
164 return MEMTX_ERROR;
165 }
166 *data = 0;
167 return MEMTX_OK;
168 }
169}
170
171static const MemoryRegionOps v7m_sysreg_ns_ops = {
172 .read_with_attrs = v7m_sysreg_ns_read,
173 .write_with_attrs = v7m_sysreg_ns_write,
174 .endianness = DEVICE_NATIVE_ENDIAN,
175};
176
177static MemTxResult v7m_systick_write(void *opaque, hwaddr addr,
178 uint64_t value, unsigned size,
179 MemTxAttrs attrs)
180{
181 ARMv7MState *s = opaque;
182 MemoryRegion *mr;
183
184
185 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
186 return memory_region_dispatch_write(mr, addr, value,
187 size_memop(size) | MO_TE, attrs);
188}
189
190static MemTxResult v7m_systick_read(void *opaque, hwaddr addr,
191 uint64_t *data, unsigned size,
192 MemTxAttrs attrs)
193{
194 ARMv7MState *s = opaque;
195 MemoryRegion *mr;
196
197
198 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
199 return memory_region_dispatch_read(mr, addr, data, size_memop(size) | MO_TE,
200 attrs);
201}
202
203static const MemoryRegionOps v7m_systick_ops = {
204 .read_with_attrs = v7m_systick_read,
205 .write_with_attrs = v7m_systick_write,
206 .endianness = DEVICE_NATIVE_ENDIAN,
207};
208
209
210
211
212
213static MemTxResult ppb_default_read(void *opaque, hwaddr addr,
214 uint64_t *data, unsigned size,
215 MemTxAttrs attrs)
216{
217 qemu_log_mask(LOG_UNIMP, "Read of unassigned area of PPB: offset 0x%x\n",
218 (uint32_t)addr);
219 if (attrs.user) {
220 return MEMTX_ERROR;
221 }
222 *data = 0;
223 return MEMTX_OK;
224}
225
226static MemTxResult ppb_default_write(void *opaque, hwaddr addr,
227 uint64_t value, unsigned size,
228 MemTxAttrs attrs)
229{
230 qemu_log_mask(LOG_UNIMP, "Write of unassigned area of PPB: offset 0x%x\n",
231 (uint32_t)addr);
232 if (attrs.user) {
233 return MEMTX_ERROR;
234 }
235 return MEMTX_OK;
236}
237
238static const MemoryRegionOps ppb_default_ops = {
239 .read_with_attrs = ppb_default_read,
240 .write_with_attrs = ppb_default_write,
241 .endianness = DEVICE_NATIVE_ENDIAN,
242 .valid.min_access_size = 1,
243 .valid.max_access_size = 8,
244};
245
246static void armv7m_instance_init(Object *obj)
247{
248 ARMv7MState *s = ARMV7M(obj);
249 int i;
250
251
252
253 memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
254
255 object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
256 object_property_add_alias(obj, "num-irq",
257 OBJECT(&s->nvic), "num-irq");
258
259 object_initialize_child(obj, "systick-reg-ns", &s->systick[M_REG_NS],
260 TYPE_SYSTICK);
261
262
263
264
265
266 for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
267 object_initialize_child(obj, "bitband[*]", &s->bitband[i],
268 TYPE_BITBAND);
269 }
270
271 s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk", NULL, NULL, 0);
272 s->cpuclk = qdev_init_clock_in(DEVICE(obj), "cpuclk", NULL, NULL, 0);
273}
274
275static void armv7m_realize(DeviceState *dev, Error **errp)
276{
277 ARMv7MState *s = ARMV7M(dev);
278 SysBusDevice *sbd;
279 Error *err = NULL;
280 int i;
281
282 if (!s->board_memory) {
283 error_setg(errp, "memory property was not set");
284 return;
285 }
286
287 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
288
289 s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
290 &err, NULL));
291 if (err != NULL) {
292 error_propagate(errp, err);
293 return;
294 }
295
296 object_property_set_link(OBJECT(s->cpu), "memory", OBJECT(&s->container),
297 &error_abort);
298 if (object_property_find(OBJECT(s->cpu), "idau")) {
299 object_property_set_link(OBJECT(s->cpu), "idau", s->idau,
300 &error_abort);
301 }
302 if (object_property_find(OBJECT(s->cpu), "init-svtor")) {
303 if (!object_property_set_uint(OBJECT(s->cpu), "init-svtor",
304 s->init_svtor, errp)) {
305 return;
306 }
307 }
308 if (object_property_find(OBJECT(s->cpu), "init-nsvtor")) {
309 if (!object_property_set_uint(OBJECT(s->cpu), "init-nsvtor",
310 s->init_nsvtor, errp)) {
311 return;
312 }
313 }
314 if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
315 if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
316 s->start_powered_off, errp)) {
317 return;
318 }
319 }
320 if (object_property_find(OBJECT(s->cpu), "vfp")) {
321 if (!object_property_set_bool(OBJECT(s->cpu), "vfp", s->vfp, errp)) {
322 return;
323 }
324 }
325 if (object_property_find(OBJECT(s->cpu), "dsp")) {
326 if (!object_property_set_bool(OBJECT(s->cpu), "dsp", s->dsp, errp)) {
327 return;
328 }
329 }
330
331
332
333
334
335 s->cpu->env.nvic = &s->nvic;
336 s->nvic.cpu = s->cpu;
337
338 if (!qdev_realize(DEVICE(s->cpu), NULL, errp)) {
339 return;
340 }
341
342
343 if (!sysbus_realize(SYS_BUS_DEVICE(&s->nvic), errp)) {
344 return;
345 }
346
347
348
349
350
351 qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
352 qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
353 qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
402 "nvic-default", 0x100000);
403 memory_region_add_subregion_overlap(&s->container, 0xe0000000,
404 &s->defaultmem, -1);
405
406
407 sbd = SYS_BUS_DEVICE(&s->nvic);
408 sysbus_connect_irq(sbd, 0,
409 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
410
411 memory_region_add_subregion(&s->container, 0xe000e000,
412 sysbus_mmio_get_region(sbd, 0));
413 if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
414
415 memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
416 &v7m_sysreg_ns_ops,
417 sysbus_mmio_get_region(sbd, 0),
418 "nvic_sysregs_ns", 0x1000);
419 memory_region_add_subregion(&s->container, 0xe002e000,
420 &s->sysreg_ns_mem);
421 }
422
423
424 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "refclk", s->refclk);
425 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "cpuclk", s->cpuclk);
426 if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), errp)) {
427 return;
428 }
429 sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
430 qdev_get_gpio_in_named(DEVICE(&s->nvic),
431 "systick-trigger", M_REG_NS));
432
433 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
434
435
436
437
438
439 object_initialize_child(OBJECT(dev), "systick-reg-s",
440 &s->systick[M_REG_S], TYPE_SYSTICK);
441 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "refclk",
442 s->refclk);
443 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "cpuclk",
444 s->cpuclk);
445
446 if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_S]), errp)) {
447 return;
448 }
449 sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
450 qdev_get_gpio_in_named(DEVICE(&s->nvic),
451 "systick-trigger", M_REG_S));
452 }
453
454 memory_region_init_io(&s->systickmem, OBJECT(s),
455 &v7m_systick_ops, s,
456 "v7m_systick", 0xe0);
457
458 memory_region_add_subregion_overlap(&s->container, 0xe000e010,
459 &s->systickmem, 1);
460 if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
461 memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
462 &v7m_sysreg_ns_ops, &s->systickmem,
463 "v7m_systick_ns", 0xe0);
464 memory_region_add_subregion_overlap(&s->container, 0xe002e010,
465 &s->systick_ns_mem, 1);
466 }
467
468
469 if (cpu_isar_feature(aa32_ras, s->cpu)) {
470 object_initialize_child(OBJECT(dev), "armv7m-ras",
471 &s->ras, TYPE_ARMV7M_RAS);
472 sbd = SYS_BUS_DEVICE(&s->ras);
473 if (!sysbus_realize(sbd, errp)) {
474 return;
475 }
476 memory_region_add_subregion_overlap(&s->container, 0xe0005000,
477 sysbus_mmio_get_region(sbd, 0), 1);
478 }
479
480 for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
481 if (s->enable_bitband) {
482 Object *obj = OBJECT(&s->bitband[i]);
483 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
484
485 if (!object_property_set_int(obj, "base",
486 bitband_input_addr[i], errp)) {
487 return;
488 }
489 object_property_set_link(obj, "source-memory",
490 OBJECT(s->board_memory), &error_abort);
491 if (!sysbus_realize(SYS_BUS_DEVICE(obj), errp)) {
492 return;
493 }
494
495 memory_region_add_subregion(&s->container, bitband_output_addr[i],
496 sysbus_mmio_get_region(sbd, 0));
497 } else {
498 object_unparent(OBJECT(&s->bitband[i]));
499 }
500 }
501}
502
503static Property armv7m_properties[] = {
504 DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type),
505 DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
506 MemoryRegion *),
507 DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
508 DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
509 DEFINE_PROP_UINT32("init-nsvtor", ARMv7MState, init_nsvtor, 0),
510 DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
511 DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
512 false),
513 DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
514 DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
515 DEFINE_PROP_END_OF_LIST(),
516};
517
518static const VMStateDescription vmstate_armv7m = {
519 .name = "armv7m",
520 .version_id = 1,
521 .minimum_version_id = 1,
522 .fields = (VMStateField[]) {
523 VMSTATE_CLOCK(refclk, SysTickState),
524 VMSTATE_CLOCK(cpuclk, SysTickState),
525 VMSTATE_END_OF_LIST()
526 }
527};
528
529static void armv7m_class_init(ObjectClass *klass, void *data)
530{
531 DeviceClass *dc = DEVICE_CLASS(klass);
532
533 dc->realize = armv7m_realize;
534 dc->vmsd = &vmstate_armv7m;
535 device_class_set_props(dc, armv7m_properties);
536}
537
538static const TypeInfo armv7m_info = {
539 .name = TYPE_ARMV7M,
540 .parent = TYPE_SYS_BUS_DEVICE,
541 .instance_size = sizeof(ARMv7MState),
542 .instance_init = armv7m_instance_init,
543 .class_init = armv7m_class_init,
544};
545
546static void armv7m_reset(void *opaque)
547{
548 ARMCPU *cpu = opaque;
549
550 cpu_reset(CPU(cpu));
551}
552
553void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
554{
555 int image_size;
556 uint64_t entry;
557 int big_endian;
558 AddressSpace *as;
559 int asidx;
560 CPUState *cs = CPU(cpu);
561
562#ifdef TARGET_WORDS_BIGENDIAN
563 big_endian = 1;
564#else
565 big_endian = 0;
566#endif
567
568 if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
569 asidx = ARMASIdx_S;
570 } else {
571 asidx = ARMASIdx_NS;
572 }
573 as = cpu_get_address_space(cs, asidx);
574
575 if (kernel_filename) {
576 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
577 &entry, NULL, NULL,
578 NULL, big_endian, EM_ARM, 1, 0, as);
579 if (image_size < 0) {
580 image_size = load_image_targphys_as(kernel_filename, 0,
581 mem_size, as);
582 }
583 if (image_size < 0) {
584 error_report("Could not load kernel '%s'", kernel_filename);
585 exit(1);
586 }
587 }
588
589
590
591
592
593
594
595
596
597 qemu_register_reset(armv7m_reset, cpu);
598}
599
600static Property bitband_properties[] = {
601 DEFINE_PROP_UINT32("base", BitBandState, base, 0),
602 DEFINE_PROP_LINK("source-memory", BitBandState, source_memory,
603 TYPE_MEMORY_REGION, MemoryRegion *),
604 DEFINE_PROP_END_OF_LIST(),
605};
606
607static void bitband_class_init(ObjectClass *klass, void *data)
608{
609 DeviceClass *dc = DEVICE_CLASS(klass);
610
611 dc->realize = bitband_realize;
612 device_class_set_props(dc, bitband_properties);
613}
614
615static const TypeInfo bitband_info = {
616 .name = TYPE_BITBAND,
617 .parent = TYPE_SYS_BUS_DEVICE,
618 .instance_size = sizeof(BitBandState),
619 .instance_init = bitband_init,
620 .class_init = bitband_class_init,
621};
622
623static void armv7m_register_types(void)
624{
625 type_register_static(&bitband_info);
626 type_register_static(&armv7m_info);
627}
628
629type_init(armv7m_register_types)
630