summary refs log tree commit diff stats
path: root/hw/intc/xive.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-26 08:38:19 +0200
committerRichard Henderson <richard.henderson@linaro.org>2023-06-26 08:38:19 +0200
commitf9925abbda1c324d901d8e7fe63bad09a35ae740 (patch)
tree18c2af50822bf8974eff8be3bea177190e01ebdf /hw/intc/xive.c
parent79dbd910c9ea6ca38f8e1b2616b1e5e885b85bd3 (diff)
parent5eb63b88d0ac259c2f49e62b6dcc6527a5caf255 (diff)
downloadfocaccia-qemu-f9925abbda1c324d901d8e7fe63bad09a35ae740.tar.gz
focaccia-qemu-f9925abbda1c324d901d8e7fe63bad09a35ae740.zip
Merge tag 'pull-ppc-20230626' of https://github.com/legoater/qemu into staging
ppc queue:

* New maintainers
* Nested implementation cleanups
* Various cleanups of the CPU implementation
* SMT support for pseries
* Improvements of the XIVE2 TIMA modeling
* Extra avocado tests for pseries

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmSZKF8ACgkQUaNDx8/7
# 7KGSiBAAlHC4S9J5ujzTIojaWY72d2ZinkC+WpBus9Wr91DqaUSUd/JbzDxQCvXh
# dBWEbcyQ+abb8M3OQ3fMq9TfD2/LhxxXb+uwHIJ+ylITBnsRVCQv/4/gi3EkpRid
# h4q3wYH8OYNfCQd/cWYXNgCSNj1nS9sRrEKFXaB0JeQWHzHxriJS/SoIhilqvUru
# LFEytWNb3bxRkEkt8oAetOa9+DNLowUQ9IdzswqGcib09po3b1k4+ThfcvzU9nAc
# ek31/h1W6cJbOJcgRO2dhWUZYp7cfmcnOa02E84tGFvvY/kYbjzPZZnoniSXD4uf
# YWFCoB3VxUoZ/YKCT/pDKHVdXmLLrfckNbo9vQNEcwmjr8m0Q3d1ewD5O9oNRpgN
# H0QMENfsdojztosOm3KPQ20aqNf1R7rQegYTiWf3B2fKZ6PIqnn3tBPxaEDkH7NC
# GTAKnBhF48lcHSF/4XOfGdmqhGgPRWX/Tv0wia7RY/A4NEfiIImIu+nYSGNBbu3y
# 7xlmtcumTlsRityOZnYI3bN5ubv++XPwU5NIJPACqvAbhif2rf1vQ9rMkkK785GL
# ciJ/5f6zXsLU7DfWP+qbTBizchQgigXnRZEEc7Seo6Bwtru22oxug0qQZ5QCgyXl
# Fg5Xuoq/6T4JC75pvxh1BjVlZc3Okzbfmsj+aZNrXO581HVJ2JI=
# =XLtJ
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 26 Jun 2023 07:55:43 AM CEST
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* tag 'pull-ppc-20230626' of https://github.com/legoater/qemu: (30 commits)
  tests/avocado: ppc test VOF bios Linux boot
  pnv/xive2: Check TIMA special ops against a dedicated array for P10
  pnv/xive2: Add a get_config() method on the presenter class
  tests/avocado: Add ppc64 pseries multiprocessor boot tests
  tests/avocado: boot ppc64 pseries to Linux VFS mount
  spapr: TCG allow up to 8-thread SMT on POWER8 and newer CPUs
  hw/ppc/spapr: Test whether TCG is enabled with tcg_enabled()
  target/ppc: Add msgsnd/p and DPDES SMT support
  target/ppc: Add support for SMT CTRL register
  target/ppc: Add initial flags and helpers for SMT support
  target/ppc: Fix sc instruction handling of LEV field
  target/ppc: Better CTRL SPR implementation
  target/ppc: Add ISA v3.1 LEV indication in SRR1 for system call interrupts
  target/ppc: Implement HEIR SPR
  target/ppc: Add SRR1 prefix indication to interrupt handlers
  target/ppc: Change partition-scope translate interface
  target/ppc: Fix instruction loading endianness in alignment interrupt
  ppc/spapr: Move spapr nested HV to a new file
  ppc/spapr: load and store l2 state with helper functions
  ppc/spapr: Add a nested state struct
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/intc/xive.c')
-rw-r--r--hw/intc/xive.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index 5204c14b87..84c079b034 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -20,6 +20,7 @@
 #include "monitor/monitor.h"
 #include "hw/irq.h"
 #include "hw/ppc/xive.h"
+#include "hw/ppc/xive2.h"
 #include "hw/ppc/xive_regs.h"
 #include "trace.h"
 
@@ -461,6 +462,13 @@ static void xive_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx,
     }
 }
 
+static uint32_t xive_presenter_get_config(XivePresenter *xptr)
+{
+    XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+
+    return xpc->get_config(xptr);
+}
+
 /*
  * Define a mapping of "special" operations depending on the TIMA page
  * offset and the size of the operation.
@@ -497,14 +505,47 @@ static const XiveTmOp xive_tm_operations[] = {
     { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  8, NULL, xive_tm_pull_pool_ctx },
 };
 
-static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
+static const XiveTmOp xive2_tm_operations[] = {
+    /*
+     * MMIOs below 2K : raw values and special operations without side
+     * effects
+     */
+    { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR,   1, xive_tm_set_os_cppr, NULL },
+    { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2,  4, xive2_tm_push_os_ctx, NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
+    { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
+
+    /* MMIOs above 2K : special operations with side effects */
+    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG,     2, NULL, xive_tm_ack_os_reg },
+    { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    4, NULL, xive2_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX,    8, NULL, xive2_tm_pull_os_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG,     2, NULL, xive_tm_ack_hv_reg },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  4, NULL, xive_tm_pull_pool_ctx },
+    { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX,  8, NULL, xive_tm_pull_pool_ctx },
+};
+
+static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
+                                       unsigned size, bool write)
 {
     uint8_t page_offset = (offset >> TM_SHIFT) & 0x3;
     uint32_t op_offset = offset & TM_ADDRESS_MASK;
-    int i;
+    const XiveTmOp *tm_ops;
+    int i, tm_ops_count;
+    uint32_t cfg;
+
+    cfg = xive_presenter_get_config(xptr);
+    if (cfg & XIVE_PRESENTER_GEN1_TIMA_OS) {
+        tm_ops = xive_tm_operations;
+        tm_ops_count = ARRAY_SIZE(xive_tm_operations);
+    } else {
+        tm_ops = xive2_tm_operations;
+        tm_ops_count = ARRAY_SIZE(xive2_tm_operations);
+    }
 
-    for (i = 0; i < ARRAY_SIZE(xive_tm_operations); i++) {
-        const XiveTmOp *xto = &xive_tm_operations[i];
+    for (i = 0; i < tm_ops_count; i++) {
+        const XiveTmOp *xto = &tm_ops[i];
 
         /* Accesses done from a more privileged TIMA page is allowed */
         if (xto->page_offset >= page_offset &&
@@ -535,7 +576,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
      * First, check for special operations in the 2K region
      */
     if (offset & TM_SPECIAL_OP) {
-        xto = xive_tm_find_op(offset, size, true);
+        xto = xive_tm_find_op(tctx->xptr, offset, size, true);
         if (!xto) {
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
                           "@%"HWADDR_PRIx"\n", offset);
@@ -548,7 +589,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
     /*
      * Then, for special operations in the region below 2K.
      */
-    xto = xive_tm_find_op(offset, size, true);
+    xto = xive_tm_find_op(tctx->xptr, offset, size, true);
     if (xto) {
         xto->write_handler(xptr, tctx, offset, value, size);
         return;
@@ -574,7 +615,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
      * First, check for special operations in the 2K region
      */
     if (offset & TM_SPECIAL_OP) {
-        xto = xive_tm_find_op(offset, size, false);
+        xto = xive_tm_find_op(tctx->xptr, offset, size, false);
         if (!xto) {
             qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid read access to TIMA"
                           "@%"HWADDR_PRIx"\n", offset);
@@ -587,7 +628,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
     /*
      * Then, for special operations in the region below 2K.
      */
-    xto = xive_tm_find_op(offset, size, false);
+    xto = xive_tm_find_op(tctx->xptr, offset, size, false);
     if (xto) {
         ret = xto->read_handler(xptr, tctx, offset, size);
         goto out;