@@ -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) \
@@ -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(),
};
@@ -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;
}
@@ -217,6 +217,8 @@ struct PnvMachineState {
Notifier powerdown_notifier;
PnvPnor *pnor;
+
+ hwaddr fw_load_addr;
};
#define PNV_FDT_ADDR 0x01000000
@@ -40,6 +40,7 @@ typedef struct PnvCore {
/*< public >*/
PowerPCCPU **threads;
uint32_t pir;
+ uint64_t hrmor;
PnvChip *chip;
MemoryRegion xscom_regs;