diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index e61994cf5a..9442e5eb63 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -716,7 +716,7 @@ static void pnv_init(MachineState *machine) exit(1); } - fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE); + fw_size = load_image_targphys(fw_filename, pnv->fw_load_addr, FW_MAX_SIZE); if (fw_size < 0) { error_report("Could not load OPAL firmware '%s'", fw_filename); exit(1); @@ -1533,6 +1533,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp) PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); const char *typename = pnv_chip_core_typename(chip); int i, core_hwid; + PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); if (!object_class_by_name(typename)) { error_setg(errp, "Unable to find PowerNV CPU Core '%s'", typename); @@ -1571,6 +1572,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp) object_property_set_int(OBJECT(pnv_core), pcc->core_pir(chip, core_hwid), "pir", &error_fatal); + object_property_set_int(OBJECT(pnv_core), pnv->fw_load_addr, + "hrmor", &error_fatal); object_property_set_link(OBJECT(pnv_core), OBJECT(chip), "chip", &error_abort); object_property_set_bool(OBJECT(pnv_core), true, "realized", @@ -1767,6 +1770,22 @@ static void pnv_machine_power10_class_init(ObjectClass *oc, void *data) pmc->dt_power_mgt = pnv_dt_power_mgt; } +static bool pnv_machine_get_hb(Object *obj, Error **errp) +{ + PnvMachineState *pnv = PNV_MACHINE(obj); + + return !!pnv->fw_load_addr; +} + +static void pnv_machine_set_hb(Object *obj, bool value, Error **errp) +{ + PnvMachineState *pnv = PNV_MACHINE(obj); + + if (value) { + pnv->fw_load_addr = 0x8000000; + } +} + static void pnv_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1786,6 +1805,13 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data) */ mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE; ispc->print_info = pnv_pic_print_info; + + object_class_property_add_bool(oc, "hb-mode", + pnv_machine_get_hb, pnv_machine_set_hb, + &error_abort); + object_class_property_set_description(oc, "hb-mode", + "Use a hostboot like boot loader", + NULL); } #define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \ diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 5fe3f21e12..f7247222bc 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -56,6 +56,8 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu) env->nip = 0x10; env->msr |= MSR_HVB; /* Hypervisor mode */ + env->spr[SPR_HRMOR] = pc->hrmor; + pcc->intc_reset(pc->chip, cpu); } @@ -289,6 +291,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) static Property pnv_core_properties[] = { DEFINE_PROP_UINT32("pir", PnvCore, pir, 0), + DEFINE_PROP_UINT64("hrmor", PnvCore, hrmor, 0), DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 22b205532b..d1de98f04c 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -825,6 +825,7 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp) qemu_irq *irqs; qemu_irq_handler handler; PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); + bool hostboot_mode = !!pnv->fw_load_addr; /* let isa_bus_new() create its own bridge on SysBus otherwise * devices speficied on the command line won't find the bus and @@ -859,7 +860,9 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp) * Start disabled. The HIOMAP protocol will activate the mapping * with HIOMAP_C_CREATE_WRITE_WINDOW */ - memory_region_set_enabled(&pnv->pnor->mmio, false); + if (!hostboot_mode) { + memory_region_set_enabled(&pnv->pnor->mmio, false); + } return isa_bus; } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index d65dd32036..f225f2f6bf 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -217,6 +217,8 @@ struct PnvMachineState { Notifier powerdown_notifier; PnvPnor *pnor; + + hwaddr fw_load_addr; }; #define PNV_FDT_ADDR 0x01000000 diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h index 55eee95104..113550eb7f 100644 --- a/include/hw/ppc/pnv_core.h +++ b/include/hw/ppc/pnv_core.h @@ -40,6 +40,7 @@ typedef struct PnvCore { /*< public >*/ PowerPCCPU **threads; uint32_t pir; + uint64_t hrmor; PnvChip *chip; MemoryRegion xscom_regs;