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
288 if (!clock_has_source(s->cpuclk)) {
289 error_setg(errp, "armv7m: cpuclk must be connected");
290 return;
291 }
292
293 memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
294
295 s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
296 &err, NULL));
297 if (err != NULL) {
298 error_propagate(errp, err);
299 return;
300 }
301
302 object_property_set_link(OBJECT(s->cpu), "memory", OBJECT(&s->container),
303 &error_abort);
304 if (object_property_find(OBJECT(s->cpu), "idau")) {
305 object_property_set_link(OBJECT(s->cpu), "idau", s->idau,
306 &error_abort);
307 }
308 if (object_property_find(OBJECT(s->cpu), "init-svtor")) {
309 if (!object_property_set_uint(OBJECT(s->cpu), "init-svtor",
310 s->init_svtor, errp)) {
311 return;
312 }
313 }
314 if (object_property_find(OBJECT(s->cpu), "init-nsvtor")) {
315 if (!object_property_set_uint(OBJECT(s->cpu), "init-nsvtor",
316 s->init_nsvtor, errp)) {
317 return;
318 }
319 }
320 if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
321 if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
322 s->start_powered_off, errp)) {
323 return;
324 }
325 }
326 if (object_property_find(OBJECT(s->cpu), "vfp")) {
327 if (!object_property_set_bool(OBJECT(s->cpu), "vfp", s->vfp, errp)) {
328 return;
329 }
330 }
331 if (object_property_find(OBJECT(s->cpu), "dsp")) {
332 if (!object_property_set_bool(OBJECT(s->cpu), "dsp", s->dsp, errp)) {
333 return;
334 }
335 }
336
337
338
339
340
341 s->cpu->env.nvic = &s->nvic;
342 s->nvic.cpu = s->cpu;
343
344 if (!qdev_realize(DEVICE(s->cpu), NULL, errp)) {
345 return;
346 }
347
348
349 if (!sysbus_realize(SYS_BUS_DEVICE(&s->nvic), errp)) {
350 return;
351 }
352
353
354
355
356
357 qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
358 qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
359 qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
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
402
403
404
405
406
407 memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
408 "nvic-default", 0x100000);
409 memory_region_add_subregion_overlap(&s->container, 0xe0000000,
410 &s->defaultmem, -1);
411
412
413 sbd = SYS_BUS_DEVICE(&s->nvic);
414 sysbus_connect_irq(sbd, 0,
415 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
416
417 memory_region_add_subregion(&s->container, 0xe000e000,
418 sysbus_mmio_get_region(sbd, 0));
419 if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
420
421 memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
422 &v7m_sysreg_ns_ops,
423 sysbus_mmio_get_region(sbd, 0),
424 "nvic_sysregs_ns", 0x1000);
425 memory_region_add_subregion(&s->container, 0xe002e000,
426 &s->sysreg_ns_mem);
427 }
428
429
430
431
432
433
434
435
436
437 if (clock_has_source(s->refclk)) {
438 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "refclk",
439 s->refclk);
440 }
441 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "cpuclk", s->cpuclk);
442 if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), errp)) {
443 return;
444 }
445 sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
446 qdev_get_gpio_in_named(DEVICE(&s->nvic),
447 "systick-trigger", M_REG_NS));
448
449 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
450
451
452
453
454
455 object_initialize_child(OBJECT(dev), "systick-reg-s",
456 &s->systick[M_REG_S], TYPE_SYSTICK);
457 if (clock_has_source(s->refclk)) {
458 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "refclk",
459 s->refclk);
460 }
461 qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "cpuclk",
462 s->cpuclk);
463
464 if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_S]), errp)) {
465 return;
466 }
467 sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
468 qdev_get_gpio_in_named(DEVICE(&s->nvic),
469 "systick-trigger", M_REG_S));
470 }
471
472 memory_region_init_io(&s->systickmem, OBJECT(s),
473 &v7m_systick_ops, s,
474 "v7m_systick", 0xe0);
475
476 memory_region_add_subregion_overlap(&s->container, 0xe000e010,
477 &s->systickmem, 1);
478 if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
479 memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
480 &v7m_sysreg_ns_ops, &s->systickmem,
481 "v7m_systick_ns", 0xe0);
482 memory_region_add_subregion_overlap(&s->container, 0xe002e010,
483 &s->systick_ns_mem, 1);
484 }
485
486
487 if (cpu_isar_feature(aa32_ras, s->cpu)) {
488 object_initialize_child(OBJECT(dev), "armv7m-ras",
489 &s->ras, TYPE_ARMV7M_RAS);
490 sbd = SYS_BUS_DEVICE(&s->ras);
491 if (!sysbus_realize(sbd, errp)) {
492 return;
493 }
494 memory_region_add_subregion_overlap(&s->container, 0xe0005000,
495 sysbus_mmio_get_region(sbd, 0), 1);
496 }
497
498 for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
499 if (s->enable_bitband) {
500 Object *obj = OBJECT(&s->bitband[i]);
501 SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
502
503 if (!object_property_set_int(obj, "base",
504 bitband_input_addr[i], errp)) {
505 return;
506 }
507 object_property_set_link(obj, "source-memory",
508 OBJECT(s->board_memory), &error_abort);
509 if (!sysbus_realize(SYS_BUS_DEVICE(obj), errp)) {
510 return;
511 }
512
513 memory_region_add_subregion(&s->container, bitband_output_addr[i],
514 sysbus_mmio_get_region(sbd, 0));
515 } else {
516 object_unparent(OBJECT(&s->bitband[i]));
517 }
518 }
519}
520
521static Property armv7m_properties[] = {
522 DEFINE_PROP_STRING("cpu-type", ARMv7MState, cpu_type),
523 DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
524 MemoryRegion *),
525 DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
526 DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
527 DEFINE_PROP_UINT32("init-nsvtor", ARMv7MState, init_nsvtor, 0),
528 DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
529 DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
530 false),
531 DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
532 DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
533 DEFINE_PROP_END_OF_LIST(),
534};
535
536static const VMStateDescription vmstate_armv7m = {
537 .name = "armv7m",
538 .version_id = 1,
539 .minimum_version_id = 1,
540 .fields = (VMStateField[]) {
541 VMSTATE_CLOCK(refclk, ARMv7MState),
542 VMSTATE_CLOCK(cpuclk, ARMv7MState),
543 VMSTATE_END_OF_LIST()
544 }
545};
546
547static void armv7m_class_init(ObjectClass *klass, void *data)
548{
549 DeviceClass *dc = DEVICE_CLASS(klass);
550
551 dc->realize = armv7m_realize;
552 dc->vmsd = &vmstate_armv7m;
553 device_class_set_props(dc, armv7m_properties);
554}
555
556static const TypeInfo armv7m_info = {
557 .name = TYPE_ARMV7M,
558 .parent = TYPE_SYS_BUS_DEVICE,
559 .instance_size = sizeof(ARMv7MState),
560 .instance_init = armv7m_instance_init,
561 .class_init = armv7m_class_init,
562};
563
564static void armv7m_reset(void *opaque)
565{
566 ARMCPU *cpu = opaque;
567
568 cpu_reset(CPU(cpu));
569}
570
571void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename,
572 hwaddr mem_base, int mem_size)
573{
574 ssize_t image_size;
575 uint64_t entry;
576 AddressSpace *as;
577 int asidx;
578 CPUState *cs = CPU(cpu);
579
580 if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
581 asidx = ARMASIdx_S;
582 } else {
583 asidx = ARMASIdx_NS;
584 }
585 as = cpu_get_address_space(cs, asidx);
586
587 if (kernel_filename) {
588 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
589 &entry, NULL, NULL,
590 NULL, 0, EM_ARM, 1, 0, as);
591 if (image_size < 0) {
592 image_size = load_image_targphys_as(kernel_filename, mem_base,
593 mem_size, as);
594 }
595 if (image_size < 0) {
596 error_report("Could not load kernel '%s'", kernel_filename);
597 exit(1);
598 }
599 }
600
601
602
603
604
605
606
607
608
609 qemu_register_reset(armv7m_reset, cpu);
610}
611
612static Property bitband_properties[] = {
613 DEFINE_PROP_UINT32("base", BitBandState, base, 0),
614 DEFINE_PROP_LINK("source-memory", BitBandState, source_memory,
615 TYPE_MEMORY_REGION, MemoryRegion *),
616 DEFINE_PROP_END_OF_LIST(),
617};
618
619static void bitband_class_init(ObjectClass *klass, void *data)
620{
621 DeviceClass *dc = DEVICE_CLASS(klass);
622
623 dc->realize = bitband_realize;
624 device_class_set_props(dc, bitband_properties);
625}
626
627static const TypeInfo bitband_info = {
628 .name = TYPE_BITBAND,
629 .parent = TYPE_SYS_BUS_DEVICE,
630 .instance_size = sizeof(BitBandState),
631 .instance_init = bitband_init,
632 .class_init = bitband_class_init,
633};
634
635static void armv7m_register_types(void)
636{
637 type_register_static(&bitband_info);
638 type_register_static(&armv7m_info);
639}
640
641type_init(armv7m_register_types)
642