PnvPsi needs to be able to save/load snapshots. Add VMSTATE information
to the device class and a post_load() method to restore dynamic data items and
memory region mappings.
Signed-off-by: Michael Kowal<[email protected]>
Signed-off-by: Caleb Schlossin<[email protected]>
---
hw/ppc/pnv_psi.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 5d947d8b52..67bc911e4b 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -25,6 +25,7 @@
#include "qemu/module.h"
#include "system/reset.h"
#include "qapi/error.h"
+#include "migration/vmstate.h"
#include "hw/ppc/fdt.h"
@@ -130,12 +131,11 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
{
PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
MemoryRegion *sysmem = get_system_memory();
- uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
/* Update MR, always remove it first */
- if (old & PSIHB_BAR_EN) {
+ if (memory_region_is_mapped(&psi->regs_mr)) {
memory_region_del_subregion(sysmem, &psi->regs_mr);
}
@@ -919,6 +919,37 @@ static const TypeInfo pnv_psi_power9_info = {
},
};
+static int vmstate_pnv_psi_post_load(void *opaque, int version_id)
+{
+ PnvPsi *psi = PNV_PSI(opaque);
+ Pnv9Psi *psi9 = PNV9_PSI(psi);
+ MemoryRegion *sysmem = get_system_memory();
+ uint64_t esb_bar;
+ hwaddr esb_addr;
+
+ /* Set the ESB MMIO mapping */
+ esb_bar = psi->regs[PSIHB_REG(PSIHB9_ESB_CI_BASE)];
+
+ if (esb_bar & PSIHB9_ESB_CI_VALID) {
+ esb_addr = esb_bar & PSIHB9_ESB_CI_ADDR_MASK;
+ memory_region_add_subregion(sysmem, esb_addr,
+ &psi9->source.esb_mmio);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_pnv_psi = {
+ .name = TYPE_PNV_PSI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = vmstate_pnv_psi_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(regs, PnvPsi, PSIHB_XSCOM_MAX),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -926,6 +957,7 @@ static void pnv_psi_power10_class_init(ObjectClass *klass,
const void *data)
static const char compat[] = "ibm,power10-psihb-x\0ibm,psihb-x";
dc->desc = "PowerNV PSI Controller POWER10";
+ dc->vmsd = &vmstate_pnv_psi;
ppc->xscom_pcba = PNV10_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV10_XSCOM_PSIHB_SIZE;