mirror of https://gitee.com/openkylin/qemu.git
ppc/pnv: Add support for "hostboot" mode
When the "hb-mode" option is activated on the powernv machine, the firmware is mapped at 0x8000000 and the HRMOR of the HW threads are set to the same address. The PNOR mapping on the FW address space of the LPC bus is left enabled to let the firmware load any other images required to boot the host. Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20200127144154.10170-4-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
59942f0ebb
commit
08c3f3a734
28
hw/ppc/pnv.c
28
hw/ppc/pnv.c
|
@ -716,7 +716,7 @@ static void pnv_init(MachineState *machine)
|
||||||
exit(1);
|
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) {
|
if (fw_size < 0) {
|
||||||
error_report("Could not load OPAL firmware '%s'", fw_filename);
|
error_report("Could not load OPAL firmware '%s'", fw_filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -1533,6 +1533,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
|
||||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
|
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
|
||||||
const char *typename = pnv_chip_core_typename(chip);
|
const char *typename = pnv_chip_core_typename(chip);
|
||||||
int i, core_hwid;
|
int i, core_hwid;
|
||||||
|
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
|
||||||
|
|
||||||
if (!object_class_by_name(typename)) {
|
if (!object_class_by_name(typename)) {
|
||||||
error_setg(errp, "Unable to find PowerNV CPU Core '%s'", 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),
|
object_property_set_int(OBJECT(pnv_core),
|
||||||
pcc->core_pir(chip, core_hwid),
|
pcc->core_pir(chip, core_hwid),
|
||||||
"pir", &error_fatal);
|
"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",
|
object_property_set_link(OBJECT(pnv_core), OBJECT(chip), "chip",
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_bool(OBJECT(pnv_core), true, "realized",
|
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;
|
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)
|
static void pnv_machine_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
MachineClass *mc = MACHINE_CLASS(oc);
|
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;
|
mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
|
||||||
ispc->print_info = pnv_pic_print_info;
|
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) \
|
#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->nip = 0x10;
|
||||||
env->msr |= MSR_HVB; /* Hypervisor mode */
|
env->msr |= MSR_HVB; /* Hypervisor mode */
|
||||||
|
|
||||||
|
env->spr[SPR_HRMOR] = pc->hrmor;
|
||||||
|
|
||||||
pcc->intc_reset(pc->chip, cpu);
|
pcc->intc_reset(pc->chip, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +291,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
static Property pnv_core_properties[] = {
|
static Property pnv_core_properties[] = {
|
||||||
DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
|
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_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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 *irqs;
|
||||||
qemu_irq_handler handler;
|
qemu_irq_handler handler;
|
||||||
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
|
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
|
/* let isa_bus_new() create its own bridge on SysBus otherwise
|
||||||
* devices speficied on the command line won't find the bus and
|
* 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
|
* Start disabled. The HIOMAP protocol will activate the mapping
|
||||||
* with HIOMAP_C_CREATE_WRITE_WINDOW
|
* 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;
|
return isa_bus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,6 +217,8 @@ struct PnvMachineState {
|
||||||
Notifier powerdown_notifier;
|
Notifier powerdown_notifier;
|
||||||
|
|
||||||
PnvPnor *pnor;
|
PnvPnor *pnor;
|
||||||
|
|
||||||
|
hwaddr fw_load_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PNV_FDT_ADDR 0x01000000
|
#define PNV_FDT_ADDR 0x01000000
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef struct PnvCore {
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
PowerPCCPU **threads;
|
PowerPCCPU **threads;
|
||||||
uint32_t pir;
|
uint32_t pir;
|
||||||
|
uint64_t hrmor;
|
||||||
PnvChip *chip;
|
PnvChip *chip;
|
||||||
|
|
||||||
MemoryRegion xscom_regs;
|
MemoryRegion xscom_regs;
|
||||||
|
|
Loading…
Reference in New Issue