diff mbox series

[v3,15/18] pnv/xive2: Add support XIVE2 P9-compat mode (or Gen1)

Message ID 20211126115349.2737605-16-clg@kaod.org
State New
Headers show
Series ppc/pnv: Extend the powernv10 machine | expand

Commit Message

Cédric Le Goater Nov. 26, 2021, 11:53 a.m. UTC
The thread interrupt management area (TIMA) is a set of pages mapped
in the Hypervisor and in the guest OS address space giving access to
the interrupt thread context registers for interrupt management, ACK,
EOI, CPPR, etc.

XIVE2 changes slightly the TIMA layout with extra bits for the new
features, larger CAM lines and the controller provides configuration
switches for backward compatibility. This is called the XIVE2
P9-compat mode, of Gen1 TIMA. It impacts the layout of the TIMA and
the availability of the internal features associated with it,
Automatic Save & Restore for instance. Using a P9 layout also means
setting the controller in such a mode at init time.

As the OPAL driver initializes the XIVE2 controller with a XIVE2/P10
TIMA directly, the XIVE2 model only has a simple support for the
compat mode in the OS TIMA.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/intc/pnv_xive2_regs.h |  6 ++++++
 hw/intc/pnv_xive2.c      | 22 +++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

Comments

Daniel Henrique Barboza Feb. 25, 2022, 4:28 p.m. UTC | #1
On 11/26/21 08:53, Cédric Le Goater wrote:
> The thread interrupt management area (TIMA) is a set of pages mapped
> in the Hypervisor and in the guest OS address space giving access to
> the interrupt thread context registers for interrupt management, ACK,
> EOI, CPPR, etc.
> 
> XIVE2 changes slightly the TIMA layout with extra bits for the new
> features, larger CAM lines and the controller provides configuration
> switches for backward compatibility. This is called the XIVE2
> P9-compat mode, of Gen1 TIMA. It impacts the layout of the TIMA and
> the availability of the internal features associated with it,
> Automatic Save & Restore for instance. Using a P9 layout also means
> setting the controller in such a mode at init time.
> 
> As the OPAL driver initializes the XIVE2 controller with a XIVE2/P10
> TIMA directly, the XIVE2 model only has a simple support for the
> compat mode in the OS TIMA.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>

>   hw/intc/pnv_xive2_regs.h |  6 ++++++
>   hw/intc/pnv_xive2.c      | 22 +++++++++++++++++-----
>   2 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/intc/pnv_xive2_regs.h b/hw/intc/pnv_xive2_regs.h
> index 46d4fb378135..902220e6be69 100644
> --- a/hw/intc/pnv_xive2_regs.h
> +++ b/hw/intc/pnv_xive2_regs.h
> @@ -60,6 +60,12 @@
>   #define    CQ_XIVE_CFG_HYP_HARD_BLKID_OVERRIDE  PPC_BIT(16)
>   #define    CQ_XIVE_CFG_HYP_HARD_BLOCK_ID        PPC_BITMASK(17, 23)
>   
> +#define    CQ_XIVE_CFG_GEN1_TIMA_OS             PPC_BIT(24)
> +#define    CQ_XIVE_CFG_GEN1_TIMA_HYP            PPC_BIT(25)
> +#define    CQ_XIVE_CFG_GEN1_TIMA_HYP_BLK0       PPC_BIT(26) /* 0 if bit[25]=0 */
> +#define    CQ_XIVE_CFG_GEN1_TIMA_CROWD_DIS      PPC_BIT(27) /* 0 if bit[25]=0 */
> +#define    CQ_XIVE_CFG_GEN1_END_ESX             PPC_BIT(28)
> +
>   /* Interrupt Controller Base Address Register - 512 pages (32M) */
>   #define X_CQ_IC_BAR                             0x08
>   #define CQ_IC_BAR                               0x040
> diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
> index 4a2649893232..b364ee3b306b 100644
> --- a/hw/intc/pnv_xive2.c
> +++ b/hw/intc/pnv_xive2.c
> @@ -444,6 +444,8 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
>       PnvChip *chip = xive->chip;
>       int count = 0;
>       int i, j;
> +    bool gen1_tima_os =
> +        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
>   
>       for (i = 0; i < chip->nr_cores; i++) {
>           PnvCore *pc = chip->cores[i];
> @@ -460,9 +462,15 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
>   
>               tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
>   
> -            ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk,
> -                                              nvt_idx, cam_ignore,
> -                                              logic_serv);
> +            if (gen1_tima_os) {
> +                ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk,
> +                                                 nvt_idx, cam_ignore,
> +                                                 logic_serv);
> +            } else {
> +                ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk,
> +                                                   nvt_idx, cam_ignore,
> +                                                   logic_serv);
> +            }
>   
>               /*
>                * Save the context and follow on to catch duplicates,
> @@ -1627,9 +1635,11 @@ static void pnv_xive2_tm_write(void *opaque, hwaddr offset,
>       PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
>       XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
>       XivePresenter *xptr = XIVE_PRESENTER(xive);
> +    bool gen1_tima_os =
> +        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
>   
>       /* TODO: should we switch the TM ops table instead ? */
> -    if (offset == HV_PUSH_OS_CTX_OFFSET) {
> +    if (!gen1_tima_os && offset == HV_PUSH_OS_CTX_OFFSET) {
>           xive2_tm_push_os_ctx(xptr, tctx, offset, value, size);
>           return;
>       }
> @@ -1644,9 +1654,11 @@ static uint64_t pnv_xive2_tm_read(void *opaque, hwaddr offset, unsigned size)
>       PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
>       XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
>       XivePresenter *xptr = XIVE_PRESENTER(xive);
> +    bool gen1_tima_os =
> +        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
>   
>       /* TODO: should we switch the TM ops table instead ? */
> -    if (offset == HV_PULL_OS_CTX_OFFSET) {
> +    if (!gen1_tima_os && offset == HV_PULL_OS_CTX_OFFSET) {
>           return xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
>       }
>
diff mbox series

Patch

diff --git a/hw/intc/pnv_xive2_regs.h b/hw/intc/pnv_xive2_regs.h
index 46d4fb378135..902220e6be69 100644
--- a/hw/intc/pnv_xive2_regs.h
+++ b/hw/intc/pnv_xive2_regs.h
@@ -60,6 +60,12 @@ 
 #define    CQ_XIVE_CFG_HYP_HARD_BLKID_OVERRIDE  PPC_BIT(16)
 #define    CQ_XIVE_CFG_HYP_HARD_BLOCK_ID        PPC_BITMASK(17, 23)
 
+#define    CQ_XIVE_CFG_GEN1_TIMA_OS             PPC_BIT(24)
+#define    CQ_XIVE_CFG_GEN1_TIMA_HYP            PPC_BIT(25)
+#define    CQ_XIVE_CFG_GEN1_TIMA_HYP_BLK0       PPC_BIT(26) /* 0 if bit[25]=0 */
+#define    CQ_XIVE_CFG_GEN1_TIMA_CROWD_DIS      PPC_BIT(27) /* 0 if bit[25]=0 */
+#define    CQ_XIVE_CFG_GEN1_END_ESX             PPC_BIT(28)
+
 /* Interrupt Controller Base Address Register - 512 pages (32M) */
 #define X_CQ_IC_BAR                             0x08
 #define CQ_IC_BAR                               0x040
diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
index 4a2649893232..b364ee3b306b 100644
--- a/hw/intc/pnv_xive2.c
+++ b/hw/intc/pnv_xive2.c
@@ -444,6 +444,8 @@  static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
     PnvChip *chip = xive->chip;
     int count = 0;
     int i, j;
+    bool gen1_tima_os =
+        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
 
     for (i = 0; i < chip->nr_cores; i++) {
         PnvCore *pc = chip->cores[i];
@@ -460,9 +462,15 @@  static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format,
 
             tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
 
-            ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk,
-                                              nvt_idx, cam_ignore,
-                                              logic_serv);
+            if (gen1_tima_os) {
+                ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk,
+                                                 nvt_idx, cam_ignore,
+                                                 logic_serv);
+            } else {
+                ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk,
+                                                   nvt_idx, cam_ignore,
+                                                   logic_serv);
+            }
 
             /*
              * Save the context and follow on to catch duplicates,
@@ -1627,9 +1635,11 @@  static void pnv_xive2_tm_write(void *opaque, hwaddr offset,
     PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
     XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
     XivePresenter *xptr = XIVE_PRESENTER(xive);
+    bool gen1_tima_os =
+        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
 
     /* TODO: should we switch the TM ops table instead ? */
-    if (offset == HV_PUSH_OS_CTX_OFFSET) {
+    if (!gen1_tima_os && offset == HV_PUSH_OS_CTX_OFFSET) {
         xive2_tm_push_os_ctx(xptr, tctx, offset, value, size);
         return;
     }
@@ -1644,9 +1654,11 @@  static uint64_t pnv_xive2_tm_read(void *opaque, hwaddr offset, unsigned size)
     PnvXive2 *xive = pnv_xive2_tm_get_xive(cpu);
     XiveTCTX *tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc);
     XivePresenter *xptr = XIVE_PRESENTER(xive);
+    bool gen1_tima_os =
+        xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;
 
     /* TODO: should we switch the TM ops table instead ? */
-    if (offset == HV_PULL_OS_CTX_OFFSET) {
+    if (!gen1_tima_os && offset == HV_PULL_OS_CTX_OFFSET) {
         return xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
     }