aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2025-05-12 13:10:24 +1000
committerCédric Le Goater <clg@redhat.com>2025-07-21 08:03:52 +0200
commit261626dce11311ba4e866272c9a2c0990c53d85c (patch)
tree9159ba126f79ae27238b818b2dddda3a3acdc9a2 /hw/intc
parent9d466ab9b6f27a5d5b7a0ec5a7ad6f60e82fafda (diff)
downloadqemu-261626dce11311ba4e866272c9a2c0990c53d85c.zip
qemu-261626dce11311ba4e866272c9a2c0990c53d85c.tar.gz
qemu-261626dce11311ba4e866272c9a2c0990c53d85c.tar.bz2
ppc/xive: Move NSR decoding into helper functions
Rather than functions to return masks to test NSR bits, have functions to test those bits directly. This should be no functional change, it just makes the code more readable. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Reviewed-by: Michael Kowal <kowal@linux.ibm.com> Reviewed-by: Caleb Schlossin <calebs@linux.ibm.com> Tested-by: Gautam Menghani <gautam@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20250512031100.439842-16-npiggin@gmail.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/xive.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index b35d2ec..8537cad 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -25,6 +25,45 @@
/*
* XIVE Thread Interrupt Management context
*/
+bool xive_nsr_indicates_exception(uint8_t ring, uint8_t nsr)
+{
+ switch (ring) {
+ case TM_QW1_OS:
+ return !!(nsr & TM_QW1_NSR_EO);
+ case TM_QW2_HV_POOL:
+ case TM_QW3_HV_PHYS:
+ return !!(nsr & TM_QW3_NSR_HE);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+bool xive_nsr_indicates_group_exception(uint8_t ring, uint8_t nsr)
+{
+ if ((nsr & TM_NSR_GRP_LVL) > 0) {
+ g_assert(xive_nsr_indicates_exception(ring, nsr));
+ return true;
+ }
+ return false;
+}
+
+uint8_t xive_nsr_exception_ring(uint8_t ring, uint8_t nsr)
+{
+ /* NSR determines if pool/phys ring is for phys or pool interrupt */
+ if ((ring == TM_QW3_HV_PHYS) || (ring == TM_QW2_HV_POOL)) {
+ uint8_t he = (nsr & TM_QW3_NSR_HE) >> 6;
+
+ if (he == TM_QW3_NSR_HE_PHYS) {
+ return TM_QW3_HV_PHYS;
+ } else if (he == TM_QW3_NSR_HE_POOL) {
+ return TM_QW2_HV_POOL;
+ } else {
+ /* Don't support LSI mode */
+ g_assert_not_reached();
+ }
+ }
+ return ring;
+}
static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring)
{
@@ -48,18 +87,12 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
qemu_irq_lower(xive_tctx_output(tctx, ring));
- if (regs[TM_NSR] != 0) {
+ if (xive_nsr_indicates_exception(ring, nsr)) {
uint8_t cppr = regs[TM_PIPR];
uint8_t alt_ring;
uint8_t *alt_regs;
- /* POOL interrupt uses IPB in QW2, POOL ring */
- if ((ring == TM_QW3_HV_PHYS) &&
- ((nsr & TM_QW3_NSR_HE) == (TM_QW3_NSR_HE_POOL << 6))) {
- alt_ring = TM_QW2_HV_POOL;
- } else {
- alt_ring = ring;
- }
+ alt_ring = xive_nsr_exception_ring(ring, nsr);
alt_regs = &tctx->regs[alt_ring];
regs[TM_CPPR] = cppr;
@@ -68,7 +101,7 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
* If the interrupt was for a specific VP, reset the pending
* buffer bit, otherwise clear the logical server indicator
*/
- if (!(regs[TM_NSR] & TM_NSR_GRP_LVL)) {
+ if (!xive_nsr_indicates_group_exception(ring, nsr)) {
alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
}