On 13/10/26 10:39, Peter Maydell wrote:
The IRS_VMAP_VMR register lets the guest mark a VM as valid.  This is
a 64-bit register similar in operation to IRS_VMAP_L2_VMTR.

We are eventually going to want to cache the information in a VM
table entry, but for the moment implement the "make valid" operation
as simply writing 1 to the VALID bit in the L2 VMTE.

Note that unlike many of the other address fields in GICv5 data
structures, we don't need to clear any of the low bits in
L1_VMTE.L2_ADDR beyond masking with R_L1_VMTE_L2_ADDR_MASK.  This is
because a level 2 VMT is always 4KB and so the alignment is fixed;
the mask clears the low 12 bits, enforcing 4KB alignment.

Signed-off-by: Peter Maydell <[email protected]>
---
  hw/intc/arm_gicv5.c                | 94 ++++++++++++++++++++++++++++++
  hw/intc/arm_gicv5_common.c         |  1 +
  hw/intc/trace-events               |  1 +
  include/hw/intc/arm_gicv5_common.h |  1 +
  include/hw/intc/arm_gicv5_regs.h   | 21 +++++++
  5 files changed, 118 insertions(+)


@@ -1472,6 +1531,22 @@ static bool config_readl(GICv5 *s, GICv5Domain domain, 
hwaddr offset,
              *data = 0;
          }
          return true;
+    case A_IRS_VMAP_VMR:
+        if (gicv5_domain_has_virt(cs, domain) && s->vmt_config[domain].valid) {
+            *data = extract64(cs->irs_vmap_vmr[domain], 0, 32);
+        } else {
+            /* RAZ/WI if no virt or no VM table */
+            *data = 0;
+        }
+        return true;
+    case A_IRS_VMAP_VMR + 4:
+        if (gicv5_domain_has_virt(cs, domain) && s->vmt_config[domain].valid) {
+            *data = extract64(cs->irs_vmap_vmr[domain], 32, 32);
+        } else {
+            /* RAZ/WI if no virt or no VM table */
+            *data = 0;
+        }
+        return true;
      case A_IRS_SPI_STATUSR:
          /*
           * QEMU writes to IRS_SPI_{CFGR,DOMAINR,SELR,VMR} take effect
@@ -1604,6 +1679,14 @@ static bool config_writel(GICv5 *s, GICv5Domain domain, 
hwaddr offset,
                                 deposit64(cs->irs_vmap_l2_vmtr[domain],
                                           32, 32, data));
          return true;
+    case A_IRS_VMAP_VMR:
+        irs_vmap_vmr_write(s, domain,
+                           deposit64(cs->irs_vmap_vmr[domain], 0, 32, data));
+        return true;
+    case A_IRS_VMAP_VMR + 4:
+        irs_vmap_vmr_write(s, domain,
+                           deposit64(cs->irs_vmap_vmr[domain], 32, 32, data));
+        return true;
      case A_IRS_SPI_SELR:
          cs->irs_spi_selr[domain] = data;
          return true;
@@ -1704,6 +1787,14 @@ static bool config_readll(GICv5 *s, GICv5Domain domain, 
hwaddr offset,
              *data = 0;
          }
          return true;
+    case A_IRS_VMAP_VMR:
+        if (gicv5_domain_has_virt(cs, domain) && s->vmt_config[domain].valid) {
+            *data = cs->irs_vmap_l2_vmtr[domain];

irs_vmap_l2_vmtr[] or irs_vmap_vmr[]?

+        } else {
+            /* RAZ/WI if no virt or no VM table */
+            *data = 0;
+        }
+        return true;
      }
return false;
@@ -1722,6 +1813,9 @@ static bool config_writell(GICv5 *s, GICv5Domain domain, 
hwaddr offset,
      case A_IRS_VMAP_L2_VMTR:
          irs_vmap_l2_vmtr_write(s, domain, data);
          return true;
+    case A_IRS_VMAP_VMR:
+        irs_vmap_vmr_write(s, domain, data);
+        return true;
      }

Reply via email to