arm_gic.c (f3b8f18ebf344ab359e8f79f6ed777e740dae77c) arm_gic.c (11411489da890ae40c182be7fa745c647e8ce399)
1/*
2 * ARM Generic/Distributed Interrupt Controller
3 *
4 * Copyright (c) 2006-2007 CodeSourcery.
5 * Written by Paul Brook
6 *
7 * This code is licensed under the GPL.
8 */

--- 627 unchanged lines hidden (view full) ---

636 gic_update_virt(s);
637 } else {
638 gic_update(s);
639 }
640 DPRINTF("ACK %d\n", irq);
641 return ret;
642}
643
1/*
2 * ARM Generic/Distributed Interrupt Controller
3 *
4 * Copyright (c) 2006-2007 CodeSourcery.
5 * Written by Paul Brook
6 *
7 * This code is licensed under the GPL.
8 */

--- 627 unchanged lines hidden (view full) ---

636 gic_update_virt(s);
637 } else {
638 gic_update(s);
639 }
640 DPRINTF("ACK %d\n", irq);
641 return ret;
642}
643
644static uint32_t gic_fullprio_mask(GICState *s, int cpu)
645{
646 /*
647 * Return a mask word which clears the unimplemented priority
648 * bits from a priority value for an interrupt. (Not to be
649 * confused with the group priority, whose mask depends on BPR.)
650 */
651 int priBits;
652
653 if (gic_is_vcpu(cpu)) {
654 priBits = GIC_VIRT_MAX_GROUP_PRIO_BITS;
655 } else {
656 priBits = s->n_prio_bits;
657 }
658 return ~0U << (8 - priBits);
659}
660
644void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
645 MemTxAttrs attrs)
646{
647 if (s->security_extn && !attrs.secure) {
648 if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) {
649 return; /* Ignore Non-secure access of Group0 IRQ */
650 }
651 val = 0x80 | (val >> 1); /* Non-secure view */
652 }
653
661void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val,
662 MemTxAttrs attrs)
663{
664 if (s->security_extn && !attrs.secure) {
665 if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) {
666 return; /* Ignore Non-secure access of Group0 IRQ */
667 }
668 val = 0x80 | (val >> 1); /* Non-secure view */
669 }
670
671 val &= gic_fullprio_mask(s, cpu);
672
654 if (irq < GIC_INTERNAL) {
655 s->priority1[irq][cpu] = val;
656 } else {
657 s->priority2[(irq) - GIC_INTERNAL] = val;
658 }
659}
660
661static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq,
662 MemTxAttrs attrs)
663{
664 uint32_t prio = GIC_DIST_GET_PRIORITY(irq, cpu);
665
666 if (s->security_extn && !attrs.secure) {
667 if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) {
668 return 0; /* Non-secure access cannot read priority of Group0 IRQ */
669 }
670 prio = (prio << 1) & 0xff; /* Non-secure view */
671 }
673 if (irq < GIC_INTERNAL) {
674 s->priority1[irq][cpu] = val;
675 } else {
676 s->priority2[(irq) - GIC_INTERNAL] = val;
677 }
678}
679
680static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq,
681 MemTxAttrs attrs)
682{
683 uint32_t prio = GIC_DIST_GET_PRIORITY(irq, cpu);
684
685 if (s->security_extn && !attrs.secure) {
686 if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) {
687 return 0; /* Non-secure access cannot read priority of Group0 IRQ */
688 }
689 prio = (prio << 1) & 0xff; /* Non-secure view */
690 }
672 return prio;
691 return prio & gic_fullprio_mask(s, cpu);
673}
674
675static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
676 MemTxAttrs attrs)
677{
678 if (gic_cpu_ns_access(s, cpu, attrs)) {
679 if (s->priority_mask[cpu] & 0x80) {
680 /* Priority Mask in upper half */
681 pmask = 0x80 | (pmask >> 1);
682 } else {
683 /* Non-secure write ignored if priority mask is in lower half */
684 return;
685 }
686 }
692}
693
694static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask,
695 MemTxAttrs attrs)
696{
697 if (gic_cpu_ns_access(s, cpu, attrs)) {
698 if (s->priority_mask[cpu] & 0x80) {
699 /* Priority Mask in upper half */
700 pmask = 0x80 | (pmask >> 1);
701 } else {
702 /* Non-secure write ignored if priority mask is in lower half */
703 return;
704 }
705 }
687 s->priority_mask[cpu] = pmask;
706 s->priority_mask[cpu] = pmask & gic_fullprio_mask(s, cpu);
688}
689
690static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs)
691{
692 uint32_t pmask = s->priority_mask[cpu];
693
694 if (gic_cpu_ns_access(s, cpu, attrs)) {
695 if (pmask & 0x80) {

--- 1354 unchanged lines hidden (view full) ---

2050 }
2051
2052 if (kvm_enabled() && !kvm_arm_supports_user_irq()) {
2053 error_setg(errp, "KVM with user space irqchip only works when the "
2054 "host kernel supports KVM_CAP_ARM_USER_IRQ");
2055 return;
2056 }
2057
707}
708
709static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs)
710{
711 uint32_t pmask = s->priority_mask[cpu];
712
713 if (gic_cpu_ns_access(s, cpu, attrs)) {
714 if (pmask & 0x80) {

--- 1354 unchanged lines hidden (view full) ---

2069 }
2070
2071 if (kvm_enabled() && !kvm_arm_supports_user_irq()) {
2072 error_setg(errp, "KVM with user space irqchip only works when the "
2073 "host kernel supports KVM_CAP_ARM_USER_IRQ");
2074 return;
2075 }
2076
2077 if (s->n_prio_bits > GIC_MAX_PRIORITY_BITS ||
2078 (s->virt_extn ? s->n_prio_bits < GIC_VIRT_MAX_GROUP_PRIO_BITS :
2079 s->n_prio_bits < GIC_MIN_PRIORITY_BITS)) {
2080 error_setg(errp, "num-priority-bits cannot be greater than %d"
2081 " or less than %d", GIC_MAX_PRIORITY_BITS,
2082 s->virt_extn ? GIC_VIRT_MAX_GROUP_PRIO_BITS :
2083 GIC_MIN_PRIORITY_BITS);
2084 return;
2085 }
2086
2058 /* This creates distributor, main CPU interface (s->cpuiomem[0]) and if
2059 * enabled, virtualization extensions related interfaces (main virtual
2060 * interface (s->vifaceiomem[0]) and virtual CPU interface).
2061 */
2062 gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, gic_virt_ops);
2063
2064 /* Extra core-specific regions for the CPU interfaces. This is
2065 * necessary for "franken-GIC" implementations, for example on

--- 49 unchanged lines hidden ---
2087 /* This creates distributor, main CPU interface (s->cpuiomem[0]) and if
2088 * enabled, virtualization extensions related interfaces (main virtual
2089 * interface (s->vifaceiomem[0]) and virtual CPU interface).
2090 */
2091 gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, gic_virt_ops);
2092
2093 /* Extra core-specific regions for the CPU interfaces. This is
2094 * necessary for "franken-GIC" implementations, for example on

--- 49 unchanged lines hidden ---