[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC PATCH] hw/intc/arm_gic_kvm.c: access the implemented APR
From: |
wanghaibin |
Subject: |
[Qemu-arm] [RFC PATCH] hw/intc/arm_gic_kvm.c: access the implemented APRn |
Date: |
Wed, 23 Aug 2017 18:22:33 +0800 |
Whether the APRn is implemented depends on how many priority
bits support. Compared with GICv3, There is no way to retrieve
this information directly from the register, so GICD_IPRIORITYR
access method is used here according to the SPEC:
To determine the number of priority bits implemented for SPIs,
software can write 0xFF to a writable
GICD_IPRIORITYR<n> priority field and read back the value stored.
Signed-off-by: wanghaibin <address@hidden>
---
hw/intc/arm_gic_kvm.c | 56 ++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 47 insertions(+), 9 deletions(-)
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index ae095d0..a2f3139 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -290,13 +290,30 @@ static void kvm_dist_put(GICState *s, uint32_t offset,
int width,
}
}
+static int kvm_arm_gic_get_pri_bits(GICState *s)
+{
+ uint32_t reg = 0xff;
+
+ /*
+ * To determine the number of priority bits implemented, Just wirte the
0xff to
+ * the first SPI(32) GICD_IPRIORITYR priority field and read back the
value
+ * stored.
+ * Note: Assume that implementations support the same number of priority
+ * bits for each PE
+ */
+ kvm_gicd_access(s, 0x400 + 0x20, 0, ®, true);
+ kvm_gicd_access(s, 0x400 + 0x20, 0, ®, false);
+
+ return 8 - ctz32(reg);
+}
+
static void kvm_arm_gic_put(GICState *s)
{
uint32_t reg;
- int i;
int cpu;
int num_cpu;
int num_irq;
+ int num_pri_bits;
/* Note: We do the restore in a slightly different order than the save
* (where the order doesn't matter and is simply ordered according to the
@@ -326,6 +343,8 @@ static void kvm_arm_gic_put(GICState *s)
abort();
}
+ num_pri_bits = kvm_arm_gic_get_pri_bits(s);
+
/* TODO: Consider checking compatibility with the IIDR ? */
/* irq_state[n].enabled -> GICD_ISENABLERn */
@@ -353,7 +372,6 @@ static void kvm_arm_gic_put(GICState *s)
kvm_dist_put(s, 0x380, 1, s->num_irq, translate_clear);
kvm_dist_put(s, 0x300, 1, s->num_irq, translate_active);
-
/* s->priorityX[irq] -> ICD_IPRIORITYRn */
kvm_dist_put(s, 0x400, 8, s->num_irq, translate_priority);
@@ -384,9 +402,18 @@ static void kvm_arm_gic_put(GICState *s)
kvm_gicc_access(s, 0x1c, cpu, ®, true);
/* s->apr[n][cpu] -> GICC_APRn */
- for (i = 0; i < 4; i++) {
- reg = s->apr[i][cpu];
- kvm_gicc_access(s, 0xd0 + i * 4, cpu, ®, true);
+ switch (num_pri_bits) {
+ case 7:
+ reg = s->apr[3][cpu];
+ kvm_gicc_access(s, 0xd0 + 3 * 4, cpu, ®, true);
+ reg = s->apr[2][cpu];
+ kvm_gicc_access(s, 0xd0 + 2 * 4, cpu, ®, true);
+ case 6:
+ reg = s->apr[1][cpu];
+ kvm_gicc_access(s, 0xd0 + 1 * 4, cpu, ®, true);
+ default:
+ reg = s->apr[0][cpu];
+ kvm_gicc_access(s, 0xd0, cpu, ®, true);
}
}
}
@@ -396,6 +423,7 @@ static void kvm_arm_gic_get(GICState *s)
uint32_t reg;
int i;
int cpu;
+ int num_pri_bits;
/*****************************************************************
* Distributor State
@@ -448,6 +476,7 @@ static void kvm_arm_gic_get(GICState *s)
/* GICD_CPENDSGIRn -> s->sgi_pending */
kvm_dist_get(s, 0xf10, 8, GIC_NR_SGIS, translate_sgisource);
+ num_pri_bits = kvm_arm_gic_get_pri_bits(s);
/*****************************************************************
* CPU Interface(s) State
@@ -470,10 +499,19 @@ static void kvm_arm_gic_get(GICState *s)
kvm_gicc_access(s, 0x1c, cpu, ®, false);
s->abpr[cpu] = (reg & 0x7);
- /* GICC_APRn -> s->apr[n][cpu] */
- for (i = 0; i < 4; i++) {
- kvm_gicc_access(s, 0xd0 + i * 4, cpu, ®, false);
- s->apr[i][cpu] = reg;
+ /* s->apr[n][cpu] -> GICC_APRn */
+ switch (num_pri_bits) {
+ case 7:
+ kvm_gicc_access(s, 0xd0 + 3 * 4, cpu, ®, false);
+ s->apr[3][cpu] = reg;
+ kvm_gicc_access(s, 0xd0 + 2 * 4, cpu, ®, false);
+ s->apr[2][cpu] = reg;
+ case 6:
+ kvm_gicc_access(s, 0xd0 + 1 * 4, cpu, ®, false);
+ s->apr[1][cpu] = reg;
+ default:
+ kvm_gicc_access(s, 0xd0, cpu, ®, false);
+ s->apr[0][cpu] = reg;
}
}
}
--
1.8.3.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-arm] [RFC PATCH] hw/intc/arm_gic_kvm.c: access the implemented APRn,
wanghaibin <=