Merge remote-tracking branch 'origin/master' into HEAD

Resolve conflicts around apb.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Michael S. Tsirkin 2018-01-11 22:01:17 +02:00
commit acc95bc850
579 changed files with 67167 additions and 9215 deletions

View file

@ -685,6 +685,8 @@ static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
int i, j, k;
dev = qdev_create(NULL, TYPE_OPENPIC);
object_property_add_child(qdev_get_machine(), "pic", OBJECT(dev),
&error_fatal);
qdev_prop_set_uint32(dev, "model", params->mpic_version);
qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
@ -884,6 +886,8 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
/* PCI */
dev = qdev_create(NULL, "e500-pcihost");
object_property_add_child(qdev_get_machine(), "pci-host", OBJECT(dev),
&error_abort);
qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot);
qdev_prop_set_uint32(dev, "first_pin_irq", pci_irq_nrs[0]);
qdev_init_nofail(dev);

View file

@ -77,8 +77,7 @@ static const char *pnv_chip_core_typename(const PnvChip *o)
* that has a different "affinity". In practice, it means one range
* per chip.
*/
static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr start,
hwaddr size)
static void pnv_dt_memory(void *fdt, int chip_id, hwaddr start, hwaddr size)
{
char *mem_name;
uint64_t mem_reg_property[2];
@ -119,7 +118,7 @@ static int get_cpus_node(void *fdt)
* device tree, used in XSCOM to address cores and in interrupt
* servers.
*/
static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
{
CPUState *cs = CPU(DEVICE(pc->threads));
DeviceClass *dc = DEVICE_GET_CLASS(cs);
@ -228,8 +227,8 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt)
servers_prop, sizeof(servers_prop))));
}
static void powernv_populate_icp(PnvChip *chip, void *fdt, uint32_t pir,
uint32_t nr_threads)
static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
uint32_t nr_threads)
{
uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
char *name;
@ -277,13 +276,13 @@ static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt)
return offset;
}
static void powernv_populate_chip(PnvChip *chip, void *fdt)
static void pnv_dt_chip(PnvChip *chip, void *fdt)
{
const char *typename = pnv_chip_core_typename(chip);
size_t typesize = object_type_get_instance_size(typename);
int i;
pnv_xscom_populate(chip, fdt, 0);
pnv_dt_xscom(chip, fdt, 0);
/* The default LPC bus of a multichip system is on chip 0. It's
* recognized by the firmware (skiboot) using a "primary"
@ -298,20 +297,18 @@ static void powernv_populate_chip(PnvChip *chip, void *fdt)
for (i = 0; i < chip->nr_cores; i++) {
PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
powernv_create_core_node(chip, pnv_core, fdt);
pnv_dt_core(chip, pnv_core, fdt);
/* Interrupt Control Presenters (ICP). One per core. */
powernv_populate_icp(chip, fdt, pnv_core->pir,
CPU_CORE(pnv_core)->nr_threads);
pnv_dt_icp(chip, fdt, pnv_core->pir, CPU_CORE(pnv_core)->nr_threads);
}
if (chip->ram_size) {
powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
chip->ram_size);
pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
}
}
static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off)
static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
{
uint32_t io_base = d->ioport_id;
uint32_t io_regs[] = {
@ -331,7 +328,7 @@ static void powernv_populate_rtc(ISADevice *d, void *fdt, int lpc_off)
_FDT((fdt_setprop_string(fdt, node, "compatible", "pnpPNP,b00")));
}
static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
static void pnv_dt_serial(ISADevice *d, void *fdt, int lpc_off)
{
const char compatible[] = "ns16550\0pnpPNP,501";
uint32_t io_base = d->ioport_id;
@ -362,7 +359,7 @@ static void powernv_populate_serial(ISADevice *d, void *fdt, int lpc_off)
_FDT((fdt_setprop_string(fdt, node, "device_type", "serial")));
}
static void powernv_populate_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
static void pnv_dt_ipmi_bt(ISADevice *d, void *fdt, int lpc_off)
{
const char compatible[] = "bt\0ipmi-bt";
uint32_t io_base;
@ -401,17 +398,17 @@ typedef struct ForeachPopulateArgs {
int offset;
} ForeachPopulateArgs;
static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
{
ForeachPopulateArgs *args = opaque;
ISADevice *d = ISA_DEVICE(dev);
if (object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC)) {
powernv_populate_rtc(d, args->fdt, args->offset);
pnv_dt_rtc(d, args->fdt, args->offset);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL)) {
powernv_populate_serial(d, args->fdt, args->offset);
pnv_dt_serial(d, args->fdt, args->offset);
} else if (object_dynamic_cast(OBJECT(dev), "isa-ipmi-bt")) {
powernv_populate_ipmi_bt(d, args->fdt, args->offset);
pnv_dt_ipmi_bt(d, args->fdt, args->offset);
} else {
error_report("unknown isa device %s@i%x", qdev_fw_name(dev),
d->ioport_id);
@ -420,7 +417,7 @@ static int powernv_populate_isa_device(DeviceState *dev, void *opaque)
return 0;
}
static void powernv_populate_isa(ISABus *bus, void *fdt, int lpc_offset)
static void pnv_dt_isa(ISABus *bus, void *fdt, int lpc_offset)
{
ForeachPopulateArgs args = {
.fdt = fdt,
@ -429,14 +426,13 @@ static void powernv_populate_isa(ISABus *bus, void *fdt, int lpc_offset)
/* ISA devices are not necessarily parented to the ISA bus so we
* can not use object_child_foreach() */
qbus_walk_children(BUS(bus), powernv_populate_isa_device,
NULL, NULL, NULL, &args);
qbus_walk_children(BUS(bus), pnv_dt_isa_device, NULL, NULL, NULL, &args);
}
static void *powernv_create_fdt(MachineState *machine)
static void *pnv_dt_create(MachineState *machine)
{
const char plat_compat[] = "qemu,powernv\0ibm,powernv";
PnvMachineState *pnv = POWERNV_MACHINE(machine);
PnvMachineState *pnv = PNV_MACHINE(machine);
void *fdt;
char *buf;
int off;
@ -479,15 +475,15 @@ static void *powernv_create_fdt(MachineState *machine)
/* Populate device tree for each chip */
for (i = 0; i < pnv->num_chips; i++) {
powernv_populate_chip(pnv->chips[i], fdt);
pnv_dt_chip(pnv->chips[i], fdt);
}
/* Populate ISA devices on chip 0 */
lpc_offset = pnv_chip_lpc_offset(pnv->chips[0], fdt);
powernv_populate_isa(pnv->isa_bus, fdt, lpc_offset);
pnv_dt_isa(pnv->isa_bus, fdt, lpc_offset);
if (pnv->bmc) {
pnv_bmc_populate_sensors(pnv->bmc, fdt);
pnv_dt_bmc_sensors(pnv->bmc, fdt);
}
return fdt;
@ -495,17 +491,17 @@ static void *powernv_create_fdt(MachineState *machine)
static void pnv_powerdown_notify(Notifier *n, void *opaque)
{
PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
if (pnv->bmc) {
pnv_bmc_powerdown(pnv->bmc);
}
}
static void ppc_powernv_reset(void)
static void pnv_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
PnvMachineState *pnv = POWERNV_MACHINE(machine);
PnvMachineState *pnv = PNV_MACHINE(machine);
void *fdt;
Object *obj;
@ -524,7 +520,7 @@ static void ppc_powernv_reset(void)
pnv->bmc = IPMI_BMC(obj);
}
fdt = powernv_create_fdt(machine);
fdt = pnv_dt_create(machine);
/* Pack resulting tree */
_FDT((fdt_pack(fdt)));
@ -552,9 +548,9 @@ static ISABus *pnv_isa_create(PnvChip *chip)
return isa_bus;
}
static void ppc_powernv_init(MachineState *machine)
static void pnv_init(MachineState *machine)
{
PnvMachineState *pnv = POWERNV_MACHINE(machine);
PnvMachineState *pnv = PNV_MACHINE(machine);
MemoryRegion *ram;
char *fw_filename;
long fw_size;
@ -567,7 +563,7 @@ static void ppc_powernv_init(MachineState *machine)
}
ram = g_new(MemoryRegion, 1);
memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram",
memory_region_allocate_system_memory(ram, NULL, "pnv.ram",
machine->ram_size);
memory_region_add_subregion(get_system_memory(), 0, ram);
@ -655,7 +651,7 @@ static void ppc_powernv_init(MachineState *machine)
serial_hds_isa_init(pnv->isa_bus, 0, MAX_SERIAL_PORTS);
/* Create an RTC ISA device too */
rtc_init(pnv->isa_bus, 2000, NULL);
mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
/* OpenPOWER systems use a IPMI SEL Event message to notify the
* host to powerdown */
@ -974,7 +970,7 @@ static void pnv_chip_class_init(ObjectClass *klass, void *data)
static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
{
PnvMachineState *pnv = POWERNV_MACHINE(xi);
PnvMachineState *pnv = PNV_MACHINE(xi);
int i;
for (i = 0; i < pnv->num_chips; i++) {
@ -987,7 +983,7 @@ static ICSState *pnv_ics_get(XICSFabric *xi, int irq)
static void pnv_ics_resend(XICSFabric *xi)
{
PnvMachineState *pnv = POWERNV_MACHINE(xi);
PnvMachineState *pnv = PNV_MACHINE(xi);
int i;
for (i = 0; i < pnv->num_chips; i++) {
@ -1021,7 +1017,7 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
static void pnv_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
PnvMachineState *pnv = POWERNV_MACHINE(obj);
PnvMachineState *pnv = PNV_MACHINE(obj);
int i;
CPUState *cs;
@ -1039,13 +1035,13 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
static void pnv_get_num_chips(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
visit_type_uint32(v, name, &POWERNV_MACHINE(obj)->num_chips, errp);
visit_type_uint32(v, name, &PNV_MACHINE(obj)->num_chips, errp);
}
static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
PnvMachineState *pnv = POWERNV_MACHINE(obj);
PnvMachineState *pnv = PNV_MACHINE(obj);
uint32_t num_chips;
Error *local_err = NULL;
@ -1067,13 +1063,13 @@ static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name,
pnv->num_chips = num_chips;
}
static void powernv_machine_initfn(Object *obj)
static void pnv_machine_initfn(Object *obj)
{
PnvMachineState *pnv = POWERNV_MACHINE(obj);
PnvMachineState *pnv = PNV_MACHINE(obj);
pnv->num_chips = 1;
}
static void powernv_machine_class_props_init(ObjectClass *oc)
static void pnv_machine_class_props_init(ObjectClass *oc)
{
object_class_property_add(oc, "num-chips", "uint32",
pnv_get_num_chips, pnv_set_num_chips,
@ -1083,15 +1079,15 @@ static void powernv_machine_class_props_init(ObjectClass *oc)
NULL);
}
static void powernv_machine_class_init(ObjectClass *oc, void *data)
static void pnv_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);
mc->desc = "IBM PowerNV (Non-Virtualized)";
mc->init = ppc_powernv_init;
mc->reset = ppc_powernv_reset;
mc->init = pnv_init;
mc->reset = pnv_reset;
mc->max_cpus = MAX_CPUS;
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
@ -1104,7 +1100,7 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
xic->ics_resend = pnv_ics_resend;
ispc->print_info = pnv_pic_print_info;
powernv_machine_class_props_init(oc);
pnv_machine_class_props_init(oc);
}
#define DEFINE_PNV_CHIP_TYPE(type, class_initfn) \
@ -1116,11 +1112,11 @@ static void powernv_machine_class_init(ObjectClass *oc, void *data)
static const TypeInfo types[] = {
{
.name = TYPE_POWERNV_MACHINE,
.name = TYPE_PNV_MACHINE,
.parent = TYPE_MACHINE,
.instance_size = sizeof(PnvMachineState),
.instance_init = powernv_machine_initfn,
.class_init = powernv_machine_class_init,
.instance_init = pnv_machine_initfn,
.class_init = pnv_machine_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_XICS_FABRIC },
{ TYPE_INTERRUPT_STATS_PROVIDER },

View file

@ -73,7 +73,7 @@ void pnv_bmc_powerdown(IPMIBmc *bmc)
pnv_gen_oem_sel(bmc, SOFT_OFF);
}
void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt)
void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
{
int offset;
int i;

View file

@ -37,7 +37,7 @@ static const char *pnv_core_cpu_typename(PnvCore *pc)
return cpu_type;
}
static void powernv_cpu_reset(void *opaque)
static void pnv_cpu_reset(void *opaque)
{
PowerPCCPU *cpu = opaque;
CPUState *cs = CPU(cpu);
@ -54,7 +54,7 @@ static void powernv_cpu_reset(void *opaque)
env->msr |= MSR_HVB; /* Hypervisor mode */
}
static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp)
static void pnv_cpu_init(PowerPCCPU *cpu, Error **errp)
{
CPUPPCState *env = &cpu->env;
int core_pir;
@ -73,7 +73,7 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp)
/* Set time-base frequency to 512 MHz */
cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ);
qemu_register_reset(powernv_cpu_reset, cpu);
qemu_register_reset(pnv_cpu_reset, cpu);
}
/*
@ -126,7 +126,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
Error *local_err = NULL;
CPUState *cs = CPU(child);
PowerPCCPU *cpu = POWERPC_CPU(cs);
Object *obj;
object_property_set_bool(child, true, "realized", &local_err);
if (local_err) {
@ -134,21 +133,14 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
return;
}
obj = object_new(TYPE_PNV_ICP);
object_property_add_child(child, "icp", obj, NULL);
object_unref(obj);
object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
&error_abort);
object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort);
object_property_set_bool(obj, true, "realized", &local_err);
cpu->intc = icp_create(child, TYPE_PNV_ICP, xi, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
powernv_cpu_init(cpu, &local_err);
pnv_cpu_init(cpu, &local_err);
if (local_err) {
object_unparent(obj);
error_propagate(errp, local_err);
return;
}

View file

@ -92,7 +92,7 @@ enum {
#define LPC_HC_REGS_OPB_SIZE 0x00001000
static int pnv_lpc_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset)
static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
{
const char compat[] = "ibm,power8-lpc\0ibm,lpc";
char *name;
@ -146,13 +146,13 @@ static bool opb_write(PnvLpcController *lpc, uint32_t addr, uint8_t *data,
return success;
}
#define ECCB_CTL_READ (1ull << (63 - 15))
#define ECCB_CTL_READ PPC_BIT(15)
#define ECCB_CTL_SZ_LSH (63 - 7)
#define ECCB_CTL_SZ_MASK (0xfull << ECCB_CTL_SZ_LSH)
#define ECCB_CTL_ADDR_MASK 0xffffffffu;
#define ECCB_CTL_SZ_MASK PPC_BITMASK(4, 7)
#define ECCB_CTL_ADDR_MASK PPC_BITMASK(32, 63)
#define ECCB_STAT_OP_DONE (1ull << (63 - 52))
#define ECCB_STAT_OP_ERR (1ull << (63 - 52))
#define ECCB_STAT_OP_DONE PPC_BIT(52)
#define ECCB_STAT_OP_ERR PPC_BIT(52)
#define ECCB_STAT_RD_DATA_LSH (63 - 37)
#define ECCB_STAT_RD_DATA_MASK (0xffffffff << ECCB_STAT_RD_DATA_LSH)
@ -482,7 +482,7 @@ static void pnv_lpc_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
xdc->populate = pnv_lpc_populate;
xdc->dt_xscom = pnv_lpc_dt_xscom;
dc->realize = pnv_lpc_realize;
}
@ -515,7 +515,7 @@ type_init(pnv_lpc_register_types)
*/
static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
{
PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
uint32_t old_state = pnv->cpld_irqstate;
PnvLpcController *lpc = PNV_LPC(opaque);

View file

@ -510,7 +510,7 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
}
}
static int pnv_psi_populate(PnvXScomInterface *dev, void *fdt, int xscom_offset)
static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
{
const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
char *name;
@ -546,7 +546,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
xdc->populate = pnv_psi_populate;
xdc->dt_xscom = pnv_psi_dt_xscom;
dc->realize = pnv_psi_realize;
dc->props = pnv_psi_properties;

View file

@ -207,15 +207,15 @@ typedef struct ForeachPopulateArgs {
int xscom_offset;
} ForeachPopulateArgs;
static int xscom_populate_child(Object *child, void *opaque)
static int xscom_dt_child(Object *child, void *opaque)
{
if (object_dynamic_cast(child, TYPE_PNV_XSCOM_INTERFACE)) {
ForeachPopulateArgs *args = opaque;
PnvXScomInterface *xd = PNV_XSCOM_INTERFACE(child);
PnvXScomInterfaceClass *xc = PNV_XSCOM_INTERFACE_GET_CLASS(xd);
if (xc->populate) {
_FDT((xc->populate(xd, args->fdt, args->xscom_offset)));
if (xc->dt_xscom) {
_FDT((xc->dt_xscom(xd, args->fdt, args->xscom_offset)));
}
}
return 0;
@ -224,7 +224,7 @@ static int xscom_populate_child(Object *child, void *opaque)
static const char compat_p8[] = "ibm,power8-xscom\0ibm,xscom";
static const char compat_p9[] = "ibm,power9-xscom\0ibm,xscom";
int pnv_xscom_populate(PnvChip *chip, void *fdt, int root_offset)
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
{
uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)),
cpu_to_be64(PNV_XSCOM_SIZE) };
@ -255,7 +255,7 @@ int pnv_xscom_populate(PnvChip *chip, void *fdt, int root_offset)
args.fdt = fdt;
args.xscom_offset = xscom_offset;
object_child_foreach(OBJECT(chip), xscom_populate_child, &args);
object_child_foreach(OBJECT(chip), xscom_dt_child, &args);
return 0;
}

View file

@ -42,6 +42,7 @@
#include "hw/loader.h"
#include "hw/timer/mc146818rtc.h"
#include "hw/isa/pc87312.h"
#include "hw/net/ne2000-isa.h"
#include "sysemu/block-backend.h"
#include "sysemu/arch_init.h"
#include "sysemu/kvm.h"

View file

@ -641,6 +641,26 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
}
static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr)
{
MemoryDeviceInfoList *info;
for (info = list; info; info = info->next) {
MemoryDeviceInfo *value = info->value;
if (value && value->type == MEMORY_DEVICE_INFO_KIND_DIMM) {
PCDIMMDeviceInfo *pcdimm_info = value->u.dimm.data;
if (pcdimm_info->addr >= addr &&
addr < (pcdimm_info->addr + pcdimm_info->size)) {
return pcdimm_info->node;
}
}
}
return -1;
}
/*
* Adds ibm,dynamic-reconfiguration-memory node.
* Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation
@ -658,6 +678,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
lmb_size;
uint32_t *int_buf, *cur_index, buf_len;
int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1;
MemoryDeviceInfoList *dimms = NULL;
/*
* Don't create the node if there is no hotpluggable memory
@ -692,6 +713,11 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
goto out;
}
if (hotplug_lmb_start) {
MemoryDeviceInfoList **prev = &dimms;
qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
}
/* ibm,dynamic-memory */
int_buf[0] = cpu_to_be32(nr_lmbs);
cur_index++;
@ -709,7 +735,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
dynamic_memory[1] = cpu_to_be32(addr & 0xffffffff);
dynamic_memory[2] = cpu_to_be32(spapr_drc_index(drc));
dynamic_memory[3] = cpu_to_be32(0); /* reserved */
dynamic_memory[4] = cpu_to_be32(numa_get_node(addr, NULL));
dynamic_memory[4] = cpu_to_be32(spapr_pc_dimm_node(dimms, addr));
if (memory_region_present(get_system_memory(), addr)) {
dynamic_memory[5] = cpu_to_be32(SPAPR_LMB_FLAGS_ASSIGNED);
} else {
@ -732,6 +758,7 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt)
cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE;
}
qapi_free_MemoryDeviceInfoList(dimms);
ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory", int_buf, buf_len);
if (ret < 0) {
goto out;
@ -916,9 +943,8 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
_FDT(fdt_setprop_cell(fdt, rtas, "rtas-event-scan-rate",
RTAS_EVENT_SCAN_RATE));
if (msi_nonbroken) {
_FDT(fdt_setprop(fdt, rtas, "ibm,change-msix-capable", NULL, 0));
}
g_assert(msi_nonbroken);
_FDT(fdt_setprop(fdt, rtas, "ibm,change-msix-capable", NULL, 0));
/*
* According to PAPR, rtas ibm,os-term does not guarantee a return
@ -1427,7 +1453,7 @@ static int spapr_reset_drcs(Object *child, void *opaque)
return 0;
}
static void ppc_spapr_reset(void)
static void spapr_machine_reset(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
@ -1440,7 +1466,10 @@ static void ppc_spapr_reset(void)
/* Check for unknown sysbus devices */
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
spapr->max_compat_pvr)) {
/* If using KVM with radix mode available, VCPUs can be started
* without a HPT because KVM will start them in radix mode.
* Set the GR bit in PATB so that we know there is no HPT. */
@ -1475,7 +1504,7 @@ static void ppc_spapr_reset(void)
spapr_ovec_cleanup(spapr->ov5_cas);
spapr->ov5_cas = spapr_ovec_new();
ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal);
ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
}
fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
@ -1499,7 +1528,6 @@ static void ppc_spapr_reset(void)
g_free(fdt);
/* Set up the entry state */
first_ppc_cpu = POWERPC_CPU(first_cpu);
first_ppc_cpu->env.gpr[3] = fdt_addr;
first_ppc_cpu->env.gpr[5] = 0;
first_cpu->halted = 0;
@ -2265,7 +2293,7 @@ out:
}
/* pSeries LPAR / sPAPR hardware init */
static void ppc_spapr_init(MachineState *machine)
static void spapr_machine_init(MachineState *machine)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
@ -2793,7 +2821,7 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name,
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
}
static void spapr_machine_initfn(Object *obj)
static void spapr_instance_init(Object *obj)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
@ -3180,12 +3208,10 @@ void spapr_core_release(DeviceState *dev)
if (smc->pre_2_10_has_unused_icps) {
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
size_t size = object_type_get_instance_size(scc->cpu_type);
int i;
for (i = 0; i < cc->nr_threads; i++) {
CPUState *cs = CPU(sc->threads + i * size);
CPUState *cs = CPU(sc->threads[i]);
pre_2_10_vmstate_register_dummy_icp(cs->cpu_index);
}
@ -3231,7 +3257,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
CPUState *cs = CPU(core->threads);
CPUState *cs = CPU(core->threads[0]);
sPAPRDRConnector *drc;
Error *local_err = NULL;
int smt = kvmppc_smt_threads();
@ -3276,15 +3302,12 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
core_slot->cpu = OBJECT(dev);
if (smc->pre_2_10_has_unused_icps) {
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(cc));
size_t size = object_type_get_instance_size(scc->cpu_type);
int i;
for (i = 0; i < cc->nr_threads; i++) {
sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev);
void *obj = sc->threads + i * size;
cs = CPU(obj);
cs = CPU(sc->threads[i]);
pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
}
}
@ -3563,6 +3586,139 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
return cpu ? ICP(cpu->intc) : NULL;
}
#define ICS_IRQ_FREE(ics, srcno) \
(!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
static int ics_find_free_block(ICSState *ics, int num, int alignnum)
{
int first, i;
for (first = 0; first < ics->nr_irqs; first += alignnum) {
if (num > (ics->nr_irqs - first)) {
return -1;
}
for (i = first; i < first + num; ++i) {
if (!ICS_IRQ_FREE(ics, i)) {
break;
}
}
if (i == (first + num)) {
return first;
}
}
return -1;
}
/*
* Allocate the IRQ number and set the IRQ type, LSI or MSI
*/
static void spapr_irq_set_lsi(sPAPRMachineState *spapr, int irq, bool lsi)
{
ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi);
}
int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi,
Error **errp)
{
ICSState *ics = spapr->ics;
int irq;
if (!ics) {
return -1;
}
if (irq_hint) {
if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
return -1;
}
irq = irq_hint;
} else {
irq = ics_find_free_block(ics, 1, 1);
if (irq < 0) {
error_setg(errp, "can't allocate IRQ: no IRQ left");
return -1;
}
irq += ics->offset;
}
spapr_irq_set_lsi(spapr, irq, lsi);
trace_spapr_irq_alloc(irq);
return irq;
}
/*
* Allocate block of consecutive IRQs, and return the number of the first IRQ in
* the block. If align==true, aligns the first IRQ number to num.
*/
int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi,
bool align, Error **errp)
{
ICSState *ics = spapr->ics;
int i, first = -1;
if (!ics) {
return -1;
}
/*
* MSIMesage::data is used for storing VIRQ so
* it has to be aligned to num to support multiple
* MSI vectors. MSI-X is not affected by this.
* The hint is used for the first IRQ, the rest should
* be allocated continuously.
*/
if (align) {
assert((num == 1) || (num == 2) || (num == 4) ||
(num == 8) || (num == 16) || (num == 32));
first = ics_find_free_block(ics, num, num);
} else {
first = ics_find_free_block(ics, num, 1);
}
if (first < 0) {
error_setg(errp, "can't find a free %d-IRQ block", num);
return -1;
}
first += ics->offset;
for (i = first; i < first + num; ++i) {
spapr_irq_set_lsi(spapr, i, lsi);
}
trace_spapr_irq_alloc_block(first, num, lsi, align);
return first;
}
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
{
ICSState *ics = spapr->ics;
int srcno = irq - ics->offset;
int i;
if (ics_valid_irq(ics, irq)) {
trace_spapr_irq_free(0, irq, num);
for (i = srcno; i < srcno + num; ++i) {
if (ICS_IRQ_FREE(ics, i)) {
trace_spapr_irq_free_warn(0, i + ics->offset);
}
memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
}
}
}
qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq)
{
ICSState *ics = spapr->ics;
if (ics_valid_irq(ics, irq)) {
return ics->qirqs[irq - ics->offset];
}
return NULL;
}
static void spapr_pic_print_info(InterruptStatsProvider *obj,
Monitor *mon)
{
@ -3622,8 +3778,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
* functions for the specific versioned machine types can override
* these details for backwards compatibility
*/
mc->init = ppc_spapr_init;
mc->reset = ppc_spapr_reset;
mc->init = spapr_machine_init;
mc->reset = spapr_machine_reset;
mc->block_default_type = IF_SCSI;
mc->max_cpus = 1024;
mc->no_parallel = 1;
@ -3670,7 +3826,7 @@ static const TypeInfo spapr_machine_info = {
.parent = TYPE_MACHINE,
.abstract = true,
.instance_size = sizeof(sPAPRMachineState),
.instance_init = spapr_machine_initfn,
.instance_init = spapr_instance_init,
.instance_finalize = spapr_machine_finalizefn,
.class_size = sizeof(sPAPRMachineClass),
.class_init = spapr_machine_class_init,
@ -3714,27 +3870,47 @@ static const TypeInfo spapr_machine_info = {
type_init(spapr_machine_register_##suffix)
/*
* pseries-2.11
* pseries-2.12
*/
static void spapr_machine_2_11_instance_options(MachineState *machine)
static void spapr_machine_2_12_instance_options(MachineState *machine)
{
}
static void spapr_machine_2_11_class_options(MachineClass *mc)
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
/* Defaults for the latest behaviour inherited from the base class */
}
DEFINE_SPAPR_MACHINE(2_11, "2.11", true);
DEFINE_SPAPR_MACHINE(2_12, "2.12", true);
/*
* pseries-2.11
*/
#define SPAPR_COMPAT_2_11 \
HW_COMPAT_2_11
static void spapr_machine_2_11_instance_options(MachineState *machine)
{
spapr_machine_2_12_instance_options(machine);
}
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
spapr_machine_2_12_class_options(mc);
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
}
DEFINE_SPAPR_MACHINE(2_11, "2.11", false);
/*
* pseries-2.10
*/
#define SPAPR_COMPAT_2_10 \
HW_COMPAT_2_10 \
HW_COMPAT_2_10
static void spapr_machine_2_10_instance_options(MachineState *machine)
{
spapr_machine_2_11_instance_options(machine);
}
static void spapr_machine_2_10_class_options(MachineClass *mc)

View file

@ -6,6 +6,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "hw/cpu/core.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "target/ppc/cpu.h"
@ -26,6 +27,7 @@ static void spapr_cpu_reset(void *opaque)
PowerPCCPU *cpu = opaque;
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
cpu_reset(cs);
@ -35,6 +37,13 @@ static void spapr_cpu_reset(void *opaque)
cs->halted = 1;
env->spr[SPR_HIOR] = 0;
/* Disable Power-saving mode Exit Cause exceptions for the CPU.
* This can cause issues when rebooting the guest if a secondary
* is awaken */
if (cs != first_cpu) {
env->spr[SPR_LPCR] &= ~pcc->lpcr_pm;
}
}
static void spapr_cpu_destroy(PowerPCCPU *cpu)
@ -79,13 +88,11 @@ const char *spapr_get_cpu_core_type(const char *cpu_type)
static void spapr_cpu_core_unrealizefn(DeviceState *dev, Error **errp)
{
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
size_t size = object_type_get_instance_size(scc->cpu_type);
CPUCore *cc = CPU_CORE(dev);
int i;
for (i = 0; i < cc->nr_threads; i++) {
void *obj = sc->threads + i * size;
Object *obj = OBJECT(sc->threads[i]);
DeviceState *dev = DEVICE(obj);
CPUState *cs = CPU(dev);
PowerPCCPU *cpu = POWERPC_CPU(cs);
@ -104,7 +111,6 @@ static void spapr_cpu_core_realize_child(Object *child,
Error *local_err = NULL;
CPUState *cs = CPU(child);
PowerPCCPU *cpu = POWERPC_CPU(cs);
Object *obj;
object_property_set_bool(child, true, "realized", &local_err);
if (local_err) {
@ -116,21 +122,14 @@ static void spapr_cpu_core_realize_child(Object *child,
goto error;
}
obj = object_new(spapr->icp_type);
object_property_add_child(child, "icp", obj, &error_abort);
object_unref(obj);
object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(spapr),
&error_abort);
object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort);
object_property_set_bool(obj, true, "realized", &local_err);
cpu->intc = icp_create(child, spapr->icp_type, XICS_FABRIC(spapr),
&local_err);
if (local_err) {
goto free_icp;
goto error;
}
return;
free_icp:
object_unparent(obj);
error:
error_propagate(errp, local_err);
}
@ -146,9 +145,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
CPUCore *cc = CPU_CORE(OBJECT(dev));
size_t size;
Error *local_err = NULL;
void *obj;
Object *obj;
int i, j;
if (!spapr) {
@ -156,18 +154,16 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
return;
}
size = object_type_get_instance_size(scc->cpu_type);
sc->threads = g_malloc0(size * cc->nr_threads);
sc->threads = g_new(PowerPCCPU *, cc->nr_threads);
for (i = 0; i < cc->nr_threads; i++) {
char id[32];
CPUState *cs;
PowerPCCPU *cpu;
obj = sc->threads + i * size;
obj = object_new(scc->cpu_type);
object_initialize(obj, size, scc->cpu_type);
cs = CPU(obj);
cpu = POWERPC_CPU(cs);
cpu = sc->threads[i] = POWERPC_CPU(obj);
cs->cpu_index = cc->core_id + i;
cpu->vcpu_id = (cc->core_id * spapr->vsmt / smp_threads) + i;
if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->vcpu_id)) {
@ -192,7 +188,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
}
for (j = 0; j < cc->nr_threads; j++) {
obj = sc->threads + j * size;
obj = OBJECT(sc->threads[j]);
spapr_cpu_core_realize_child(obj, spapr, &local_err);
if (local_err) {
@ -203,7 +199,7 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
err:
while (--i >= 0) {
obj = sc->threads + i * size;
obj = OBJECT(sc->threads[i]);
object_unparent(obj);
}
g_free(sc->threads);

View file

@ -282,8 +282,7 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
continue;
}
interrupts[0] = cpu_to_be32(source->irq);
interrupts[1] = 0;
spapr_dt_xics_irq(interrupts, source->irq, false);
_FDT(node_offset = fdt_add_subnode(fdt, event_sources, source_name));
_FDT(fdt_setprop(fdt, node_offset, "interrupts", interrupts,
@ -293,9 +292,6 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
irq_ranges[count++] = cpu_to_be32(1);
}
irq_ranges[count] = cpu_to_be32(count);
count++;
_FDT((fdt_setprop(fdt, event_sources, "interrupt-controller", NULL, 0)));
_FDT((fdt_setprop_cell(fdt, event_sources, "#interrupt-cells", 2)));
_FDT((fdt_setprop(fdt, event_sources, "interrupt-ranges",
@ -472,9 +468,8 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
rtas_event_log_queue(spapr, entry);
qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr),
rtas_event_log_to_irq(spapr,
RTAS_LOG_TYPE_EPOW)));
qemu_irq_pulse(spapr_qirq(spapr,
rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_EPOW)));
}
static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
@ -556,9 +551,8 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
rtas_event_log_queue(spapr, entry);
qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr),
rtas_event_log_to_irq(spapr,
RTAS_LOG_TYPE_HOTPLUG)));
qemu_irq_pulse(spapr_qirq(spapr,
rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_HOTPLUG)));
}
void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
@ -678,7 +672,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
spapr_event_sources_get_source(spapr->event_sources, i);
g_assert(source->enabled);
qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), source->irq));
qemu_irq_pulse(spapr_qirq(spapr, source->irq));
}
}
@ -718,7 +712,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
spapr->event_sources = spapr_event_sources_new();
spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW,
spapr_ics_alloc(spapr->ics, 0, false,
spapr_irq_alloc(spapr, 0, false,
&error_fatal));
/* NOTE: if machine supports modern/dedicated hotplug event source,
@ -731,7 +725,7 @@ void spapr_events_init(sPAPRMachineState *spapr)
*/
if (spapr->use_hotplug_event_source) {
spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG,
spapr_ics_alloc(spapr->ics, 0, false,
spapr_irq_alloc(spapr, 0, false,
&error_fatal));
}

View file

@ -13,7 +13,6 @@
#include "trace.h"
#include "kvm_ppc.h"
#include "hw/ppc/spapr_ovec.h"
#include "qemu/error-report.h"
#include "mmu-book3s-v3.h"
struct SPRSyncState {

View file

@ -314,7 +314,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
spapr_irq_free(spapr, msi->first_irq, msi->num);
if (msi_present(pdev)) {
spapr_msi_setmsg(pdev, 0, false, 0, 0);
}
@ -352,7 +352,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
/* Allocate MSIs */
irq = spapr_ics_alloc_block(spapr->ics, req_num, false,
irq = spapr_irq_alloc_block(spapr, req_num, false,
ret_intr_type == RTAS_TYPE_MSI, &err);
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
/* Release previous MSIs */
if (msi) {
spapr_ics_free(spapr->ics, msi->first_irq, msi->num);
spapr_irq_free(spapr, msi->first_irq, msi->num);
g_hash_table_remove(phb->msi, &config_addr);
}
@ -723,7 +723,7 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
trace_spapr_pci_msi_write(addr, data, irq);
qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr), irq));
qemu_irq_pulse(spapr_qirq(spapr, irq));
}
static const MemoryRegionOps spapr_msi_ops = {
@ -1675,7 +1675,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
uint32_t irq;
Error *local_err = NULL;
irq = spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_err);
irq = spapr_irq_alloc_block(spapr, 1, true, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "can't allocate LSIs: ");
@ -1696,9 +1696,9 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
/* DMA setup */
if (((sphb->page_size_mask & qemu_getrampagesize()) == 0)
&& kvm_enabled()) {
error_report("System page size 0x%lx is not enabled in page_size_mask "
"(0x%"PRIx64"). Performance may be slow",
qemu_getrampagesize(), sphb->page_size_mask);
warn_report("System page size 0x%lx is not enabled in page_size_mask "
"(0x%"PRIx64"). Performance may be slow",
qemu_getrampagesize(), sphb->page_size_mask);
}
for (i = 0; i < windows_supported; ++i) {
@ -2121,8 +2121,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
irqmap[2] = 0;
irqmap[3] = cpu_to_be32(j+1);
irqmap[4] = cpu_to_be32(xics_phandle);
irqmap[5] = cpu_to_be32(phb->lsi_table[lsi_num].irq);
irqmap[6] = cpu_to_be32(0x8);
spapr_dt_xics_irq(&irqmap[5], phb->lsi_table[lsi_num].irq, true);
}
}
/* Write interrupt map */

View file

@ -29,31 +29,6 @@
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
#define TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE "spapr-pci-vfio-host-bridge"
#define SPAPR_PCI_VFIO_HOST_BRIDGE(obj) \
OBJECT_CHECK(sPAPRPHBVFIOState, (obj), TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE)
typedef struct sPAPRPHBVFIOState sPAPRPHBVFIOState;
struct sPAPRPHBVFIOState {
sPAPRPHBState phb;
int32_t iommugroupid;
};
static Property spapr_phb_vfio_properties[] = {
DEFINE_PROP_INT32("iommu", sPAPRPHBVFIOState, iommugroupid, -1),
DEFINE_PROP_END_OF_LIST(),
};
static void spapr_phb_vfio_instance_init(Object *obj)
{
if (!qtest_enabled()) {
error_report("spapr-pci-vfio-host-bridge is deprecated");
}
}
bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
{
return vfio_eeh_as_ok(&sphb->iommu_as);
@ -218,25 +193,3 @@ int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
return RTAS_OUT_SUCCESS;
}
static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->props = spapr_phb_vfio_properties;
}
static const TypeInfo spapr_phb_vfio_info = {
.name = TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE,
.parent = TYPE_SPAPR_PCI_HOST_BRIDGE,
.instance_size = sizeof(sPAPRPHBVFIOState),
.instance_init = spapr_phb_vfio_instance_init,
.class_init = spapr_phb_vfio_class_init,
};
static void spapr_pci_vfio_register_types(void)
{
type_register_static(&spapr_phb_vfio_info);
}
type_init(spapr_pci_vfio_register_types)

View file

@ -162,6 +162,8 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
if (cpu != NULL) {
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Error *local_err = NULL;
if (!cs->halted) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
@ -173,7 +175,19 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
* new cpu enters */
kvm_cpu_synchronize_state(cs);
/* Set compatibility mode to match existing cpus */
ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);
if (local_err) {
error_report_err(local_err);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
/* Enable Power-saving mode Exit Cause exceptions for the new CPU */
env->spr[SPR_LPCR] |= pcc->lpcr_pm;
env->nip = start;
env->gpr[3] = r3;
cs->halted = 0;
@ -197,19 +211,15 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
cs->halted = 1;
qemu_cpu_kick(cs);
/*
* While stopping a CPU, the guest calls H_CPPR which
* effectively disables interrupts on XICS level.
* However decrementer interrupts in TCG can still
* wake the CPU up so here we disable interrupts in MSR
* as well.
* As rtas_start_cpu() resets the whole MSR anyway, there is
* no need to bother with specific bits, we just clear it.
*/
env->msr = 0;
/* Disable Power-saving mode Exit Cause exceptions for the CPU.
* This could deliver an interrupt on a dying CPU and crash the
* guest */
env->spr[SPR_LPCR] &= ~pcc->lpcr_pm;
}
static inline int sysparm_st(target_ulong addr, target_ulong len,

View file

@ -126,8 +126,9 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
}
if (dev->irq) {
uint32_t ints_prop[] = {cpu_to_be32(dev->irq), 0};
uint32_t ints_prop[2];
spapr_dt_xics_irq(ints_prop, dev->irq, false);
ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop,
sizeof(ints_prop));
if (ret < 0) {
@ -454,7 +455,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
dev->qdev.id = id;
}
dev->irq = spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err);
dev->irq = spapr_irq_alloc(spapr, dev->irq, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;

View file

@ -12,6 +12,10 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_num, unsigned max_irqs) "
# hw/ppc/spapr.c
spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes"
spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes"
spapr_irq_alloc(int irq) "irq %d"
spapr_irq_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d"
spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free"
# hw/ppc/spapr_hcall.c
spapr_cas_pvr_try(uint32_t pvr) "0x%x"