Lines Matching +full:cs +full:- +full:1
2 * ARM GICv3 support - common bits of emulated and KVM kernel model
27 #include "qemu/error-report.h"
30 #include "hw/qdev-properties.h"
33 #include "hw/arm/linux-boot-if.h"
37 static void gicv3_gicd_no_migration_shift_bug_post_load(GICv3State *cs) in gicv3_gicd_no_migration_shift_bug_post_load() argument
39 if (cs->gicd_no_migration_shift_bug) { in gicv3_gicd_no_migration_shift_bug_post_load()
50 memmove(cs->group, (uint8_t *)cs->group + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
51 sizeof(cs->group) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
52 memmove(cs->grpmod, (uint8_t *)cs->grpmod + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
53 sizeof(cs->grpmod) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
54 memmove(cs->enabled, (uint8_t *)cs->enabled + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
55 sizeof(cs->enabled) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
56 memmove(cs->pending, (uint8_t *)cs->pending + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
57 sizeof(cs->pending) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
58 memmove(cs->active, (uint8_t *)cs->active + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
59 sizeof(cs->active) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
60 memmove(cs->edge_trigger, (uint8_t *)cs->edge_trigger + GIC_INTERNAL / 8, in gicv3_gicd_no_migration_shift_bug_post_load()
61 sizeof(cs->edge_trigger) - GIC_INTERNAL / 8); in gicv3_gicd_no_migration_shift_bug_post_load()
68 cs->gicd_no_migration_shift_bug = true; in gicv3_gicd_no_migration_shift_bug_post_load()
76 if (c->pre_save) { in gicv3_pre_save()
77 c->pre_save(s); in gicv3_pre_save()
90 if (c->post_load) { in gicv3_post_load()
91 c->post_load(s); in gicv3_post_load()
98 GICv3CPUState *cs = opaque; in virt_state_needed() local
100 return cs->num_list_regs != 0; in virt_state_needed()
105 .version_id = 1,
106 .minimum_version_id = 1,
119 GICv3CPUState *cs = opaque; in vmstate_gicv3_cpu_pre_load() local
126 cs->icc_sre_el1 = 0x7; in vmstate_gicv3_cpu_pre_load()
132 GICv3CPUState *cs = opaque; in icc_sre_el1_reg_needed() local
134 return cs->icc_sre_el1 != 7; in icc_sre_el1_reg_needed()
139 .version_id = 1,
140 .minimum_version_id = 1,
150 GICv3CPUState *cs = opaque; in gicv4_needed() local
152 return cs->gic->revision > 3; in gicv4_needed()
157 .version_id = 1,
158 .minimum_version_id = 1,
169 GICv3CPUState *cs = opaque; in gicv3_cpu_nmi_needed() local
171 return cs->gic->nmi_support; in gicv3_cpu_nmi_needed()
176 .version_id = 1,
177 .minimum_version_id = 1,
187 .version_id = 1,
188 .minimum_version_id = 1,
224 GICv3State *cs = opaque; in gicv3_pre_load() local
232 * versions with this bug KVM -> TCG migration didn't work anyway. If the in gicv3_pre_load()
238 cs->gicd_no_migration_shift_bug = false; in gicv3_pre_load()
251 .version_id = 1,
252 .minimum_version_id = 1,
262 GICv3State *cs = opaque; in gicv3_nmi_needed() local
264 return cs->nmi_support; in gicv3_nmi_needed()
269 .version_id = 1,
270 .minimum_version_id = 1,
280 .version_id = 1,
281 .minimum_version_id = 1,
320 * [0..N-1] spi in gicv3_init_irqs_and_mmio()
322 * [N+32..N+63] PPIs for CPU 1 in gicv3_init_irqs_and_mmio()
325 i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu; in gicv3_init_irqs_and_mmio()
328 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
329 sysbus_init_irq(sbd, &s->cpu[i].parent_irq); in gicv3_init_irqs_and_mmio()
331 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
332 sysbus_init_irq(sbd, &s->cpu[i].parent_fiq); in gicv3_init_irqs_and_mmio()
334 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
335 sysbus_init_irq(sbd, &s->cpu[i].parent_virq); in gicv3_init_irqs_and_mmio()
337 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
338 sysbus_init_irq(sbd, &s->cpu[i].parent_vfiq); in gicv3_init_irqs_and_mmio()
340 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
341 sysbus_init_irq(sbd, &s->cpu[i].parent_nmi); in gicv3_init_irqs_and_mmio()
343 for (i = 0; i < s->num_cpu; i++) { in gicv3_init_irqs_and_mmio()
344 sysbus_init_irq(sbd, &s->cpu[i].parent_vnmi); in gicv3_init_irqs_and_mmio()
347 memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s, in gicv3_init_irqs_and_mmio()
349 sysbus_init_mmio(sbd, &s->iomem_dist); in gicv3_init_irqs_and_mmio()
351 s->redist_regions = g_new0(GICv3RedistRegion, s->nb_redist_regions); in gicv3_init_irqs_and_mmio()
353 for (i = 0; i < s->nb_redist_regions; i++) { in gicv3_init_irqs_and_mmio()
355 GICv3RedistRegion *region = &s->redist_regions[i]; in gicv3_init_irqs_and_mmio()
357 region->gic = s; in gicv3_init_irqs_and_mmio()
358 region->cpuidx = cpuidx; in gicv3_init_irqs_and_mmio()
359 cpuidx += s->redist_region_count[i]; in gicv3_init_irqs_and_mmio()
361 memory_region_init_io(®ion->iomem, OBJECT(s), in gicv3_init_irqs_and_mmio()
362 ops ? &ops[1] : NULL, region, name, in gicv3_init_irqs_and_mmio()
363 s->redist_region_count[i] * gicv3_redist_size(s)); in gicv3_init_irqs_and_mmio()
364 sysbus_init_mmio(sbd, ®ion->iomem); in gicv3_init_irqs_and_mmio()
378 * on the GIC revision: notably, the in-kernel KVM GIC doesn't in arm_gicv3_common_realize()
381 if (s->revision != 3 && s->revision != 4) { in arm_gicv3_common_realize()
382 error_setg(errp, "unsupported GIC revision %d", s->revision); in arm_gicv3_common_realize()
386 if (s->num_irq > GICV3_MAXIRQ) { in arm_gicv3_common_realize()
389 s->num_irq, GICV3_MAXIRQ); in arm_gicv3_common_realize()
392 if (s->num_irq < GIC_INTERNAL) { in arm_gicv3_common_realize()
395 s->num_irq, GIC_INTERNAL); in arm_gicv3_common_realize()
398 if (s->num_cpu == 0) { in arm_gicv3_common_realize()
399 error_setg(errp, "num-cpu must be at least 1"); in arm_gicv3_common_realize()
403 /* ITLinesNumber is represented as (N / 32) - 1, so this is an in arm_gicv3_common_realize()
406 * bits in a 32-bit word should be valid. in arm_gicv3_common_realize()
408 if (s->num_irq % 32) { in arm_gicv3_common_realize()
411 s->num_irq); in arm_gicv3_common_realize()
415 if (s->lpi_enable && !s->dma) { in arm_gicv3_common_realize()
416 error_setg(errp, "Redist-ITS: Guest 'sysmem' reference link not set"); in arm_gicv3_common_realize()
421 for (i = 0; i < s->nb_redist_regions; i++) { in arm_gicv3_common_realize()
422 rdist_capacity += s->redist_region_count[i]; in arm_gicv3_common_realize()
424 if (rdist_capacity != s->num_cpu) { in arm_gicv3_common_realize()
427 rdist_capacity, s->num_cpu); in arm_gicv3_common_realize()
431 if (s->lpi_enable) { in arm_gicv3_common_realize()
432 address_space_init(&s->dma_as, s->dma, in arm_gicv3_common_realize()
433 "gicv3-its-sysmem"); in arm_gicv3_common_realize()
436 s->cpu = g_new0(GICv3CPUState, s->num_cpu); in arm_gicv3_common_realize()
438 for (i = 0; i < s->num_cpu; i++) { in arm_gicv3_common_realize()
442 s->cpu[i].cpu = cpu; in arm_gicv3_common_realize()
443 s->cpu[i].gic = s; in arm_gicv3_common_realize()
445 gicv3_set_gicv3state(cpu, &s->cpu[i]); in arm_gicv3_common_realize()
447 /* Pre-construct the GICR_TYPER: in arm_gicv3_common_realize()
453 * Last == 1 if this is the last redistributor in a series of in arm_gicv3_common_realize()
456 * VLPIS == 1 if vLPIs supported (GICv4 and up) in arm_gicv3_common_realize()
457 * PLPIS == 1 if LPIs supported in arm_gicv3_common_realize()
459 cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL); in arm_gicv3_common_realize()
461 /* The CPU mp-affinity property is in MPIDR register format; squash in arm_gicv3_common_realize()
466 s->cpu[i].gicr_typer = (cpu_affid << 32) | in arm_gicv3_common_realize()
467 (1 << 24) | in arm_gicv3_common_realize()
470 if (s->lpi_enable) { in arm_gicv3_common_realize()
471 s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS; in arm_gicv3_common_realize()
472 if (s->revision > 3) { in arm_gicv3_common_realize()
473 s->cpu[i].gicr_typer |= GICR_TYPER_VLPIS; in arm_gicv3_common_realize()
483 for (i = 0; i < s->nb_redist_regions; i++) { in arm_gicv3_common_realize()
484 cpuidx += s->redist_region_count[i]; in arm_gicv3_common_realize()
485 s->cpu[cpuidx - 1].gicr_typer |= GICR_TYPER_LAST; in arm_gicv3_common_realize()
488 s->itslist = g_ptr_array_new(); in arm_gicv3_common_realize()
495 g_free(s->redist_region_count); in arm_gicv3_finalize()
503 for (i = 0; i < s->num_cpu; i++) { in arm_gicv3_common_reset_hold()
504 GICv3CPUState *cs = &s->cpu[i]; in arm_gicv3_common_reset_hold() local
506 cs->level = 0; in arm_gicv3_common_reset_hold()
507 cs->gicr_ctlr = 0; in arm_gicv3_common_reset_hold()
508 if (s->lpi_enable) { in arm_gicv3_common_reset_hold()
510 cs->gicr_ctlr |= GICR_CTLR_CES; in arm_gicv3_common_reset_hold()
512 cs->gicr_statusr[GICV3_S] = 0; in arm_gicv3_common_reset_hold()
513 cs->gicr_statusr[GICV3_NS] = 0; in arm_gicv3_common_reset_hold()
514 cs->gicr_waker = GICR_WAKER_ProcessorSleep | GICR_WAKER_ChildrenAsleep; in arm_gicv3_common_reset_hold()
515 cs->gicr_propbaser = 0; in arm_gicv3_common_reset_hold()
516 cs->gicr_pendbaser = 0; in arm_gicv3_common_reset_hold()
517 cs->gicr_vpropbaser = 0; in arm_gicv3_common_reset_hold()
518 cs->gicr_vpendbaser = 0; in arm_gicv3_common_reset_hold()
519 /* If we're resetting a TZ-aware GIC as if secure firmware in arm_gicv3_common_reset_hold()
520 * had set it up ready to start a kernel in non-secure, we in arm_gicv3_common_reset_hold()
521 * need to set interrupts to group 1 so the kernel can use them. in arm_gicv3_common_reset_hold()
524 if (s->irq_reset_nonsecure) { in arm_gicv3_common_reset_hold()
525 cs->gicr_igroupr0 = 0xffffffff; in arm_gicv3_common_reset_hold()
527 cs->gicr_igroupr0 = 0; in arm_gicv3_common_reset_hold()
530 cs->gicr_ienabler0 = 0; in arm_gicv3_common_reset_hold()
531 cs->gicr_ipendr0 = 0; in arm_gicv3_common_reset_hold()
532 cs->gicr_iactiver0 = 0; in arm_gicv3_common_reset_hold()
533 cs->edge_trigger = 0xffff; in arm_gicv3_common_reset_hold()
534 cs->gicr_igrpmodr0 = 0; in arm_gicv3_common_reset_hold()
535 cs->gicr_nsacr = 0; in arm_gicv3_common_reset_hold()
536 memset(cs->gicr_ipriorityr, 0, sizeof(cs->gicr_ipriorityr)); in arm_gicv3_common_reset_hold()
538 cs->hppi.prio = 0xff; in arm_gicv3_common_reset_hold()
539 cs->hppi.nmi = false; in arm_gicv3_common_reset_hold()
540 cs->hpplpi.prio = 0xff; in arm_gicv3_common_reset_hold()
541 cs->hpplpi.nmi = false; in arm_gicv3_common_reset_hold()
542 cs->hppvlpi.prio = 0xff; in arm_gicv3_common_reset_hold()
543 cs->hppvlpi.nmi = false; in arm_gicv3_common_reset_hold()
551 if (s->security_extn) { in arm_gicv3_common_reset_hold()
552 s->gicd_ctlr = GICD_CTLR_ARE_S | GICD_CTLR_ARE_NS; in arm_gicv3_common_reset_hold()
554 s->gicd_ctlr = GICD_CTLR_DS | GICD_CTLR_ARE; in arm_gicv3_common_reset_hold()
557 s->gicd_statusr[GICV3_S] = 0; in arm_gicv3_common_reset_hold()
558 s->gicd_statusr[GICV3_NS] = 0; in arm_gicv3_common_reset_hold()
560 memset(s->group, 0, sizeof(s->group)); in arm_gicv3_common_reset_hold()
561 memset(s->grpmod, 0, sizeof(s->grpmod)); in arm_gicv3_common_reset_hold()
562 memset(s->enabled, 0, sizeof(s->enabled)); in arm_gicv3_common_reset_hold()
563 memset(s->pending, 0, sizeof(s->pending)); in arm_gicv3_common_reset_hold()
564 memset(s->active, 0, sizeof(s->active)); in arm_gicv3_common_reset_hold()
565 memset(s->level, 0, sizeof(s->level)); in arm_gicv3_common_reset_hold()
566 memset(s->edge_trigger, 0, sizeof(s->edge_trigger)); in arm_gicv3_common_reset_hold()
567 memset(s->gicd_ipriority, 0, sizeof(s->gicd_ipriority)); in arm_gicv3_common_reset_hold()
568 memset(s->gicd_irouter, 0, sizeof(s->gicd_irouter)); in arm_gicv3_common_reset_hold()
569 memset(s->gicd_nsacr, 0, sizeof(s->gicd_nsacr)); in arm_gicv3_common_reset_hold()
578 if (s->irq_reset_nonsecure) { in arm_gicv3_common_reset_hold()
579 /* If we're resetting a TZ-aware GIC as if secure firmware in arm_gicv3_common_reset_hold()
580 * had set it up ready to start a kernel in non-secure, we in arm_gicv3_common_reset_hold()
581 * need to set interrupts to group 1 so the kernel can use them. in arm_gicv3_common_reset_hold()
584 for (i = GIC_INTERNAL; i < s->num_irq; i++) { in arm_gicv3_common_reset_hold()
588 s->gicd_no_migration_shift_bug = true; in arm_gicv3_common_reset_hold()
596 if (s->security_extn && !secure_boot) { in arm_gic_common_linux_init()
601 * this mode QEMU is acting as a minimalist firmware-and-bootloader in arm_gic_common_linux_init()
604 s->irq_reset_nonsecure = true; in arm_gic_common_linux_init()
609 DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
610 DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
612 DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
613 DEFINE_PROP_BOOL("has-nmi", GICv3State, nmi_support, 0),
614 DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
619 DEFINE_PROP_BOOL("force-8-bit-prio", GICv3State, force_8bit_prio, 0),
620 DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
633 rc->phases.hold = arm_gicv3_common_reset_hold; in arm_gicv3_common_class_init()
634 dc->realize = arm_gicv3_common_realize; in arm_gicv3_common_class_init()
636 dc->vmsd = &vmstate_gicv3; in arm_gicv3_common_class_init()
637 albifc->arm_linux_init = arm_gic_common_linux_init; in arm_gicv3_common_class_init()
664 return "kvm-arm-gicv3"; in type_init()
668 exit(1); in type_init()
670 return "arm-gicv3"; in type_init()