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; -- 2.47.3
