mirror of https://github.com/xemu-project/xemu.git
ppc patch queue 2017-06-09
This batch contains more patches to rework the pseries machine hotplug infrastructure, plus an assorted batch of bugfixes. It contains a start on fixes to restore migration from older machine types on older versions which was broken by some xics changes. There are still a few missing pieces here, though. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJZOjFrAAoJEGw4ysog2bOS7bUP/3CNnd/eP+NPwK96ZdiRpYF4 sYLyYweev7D+Lk9johJs7JzZwAsxlveGOMEFslUGXeG4aK9VPl8Xw/A9fJGE+epM ixlcQRREyudHV5H7Pc1+gqy4tVPIwaUcfEYZ0osWlzXgAIzJPLWFxO8GNXpRKXD+ Kjscqy+dc7Rp07+Yta5qQvPnPQmz9gcTB+CeY7aGvjf6dkofnj7wGoHsfuy1qifX jk4TTFY+5I4NTsI4H3F1DKpYkOwlUt3nSIVBeQI0eLeeVNZU4vJ6Uug6iMNiqmJ1 m+zaDmKVdninJKbGpG9wmaf3Z471WWGScsXGNSTIqWoQBfeUDutR1XCd+NlCmXyy /CxgejhW96m06TIN3n0Unh5RCNNfP5UMxITgjmwoM4iN2EEJXoUGsVqS3oJdf2ct wOiiSgCB9hMdV191jIPxjc/CAjuZtpJHIa4liEc3WwmUzoOXCs/vAyvEZe1UXB8/ BU3OUFdvtX6cuMWS0tbB9MM7wHR3I/ZRyWSSQW+e9m7Qq2eIcAw8zZLazFI6t5vf qDL3dYulhu6bA9et7weCuapdZA8CDcpU2xA1+C6dxZxfSvDTCDUIdojO6InhGmpG ual58ajW15zhUwNeDsY5WIHRe7F3TvsKXf95RYtIXvuoERsGwBYAMFT+gjS7c3M7 tEycIdLxXN/AsjP4v5wj =a4tH -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.10-20170609' into staging ppc patch queue 2017-06-09 This batch contains more patches to rework the pseries machine hotplug infrastructure, plus an assorted batch of bugfixes. It contains a start on fixes to restore migration from older machine types on older versions which was broken by some xics changes. There are still a few missing pieces here, though. # gpg: Signature made Fri 09 Jun 2017 06:26:03 BST # gpg: using RSA key 0x6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.10-20170609: Revert "spapr: fix memory hot-unplugging" xics: drop ICPStateClass::cpu_setup() handler xics: setup cpu at realize time xics: pass appropriate types to realize() handlers. xics: introduce macros for ICP/ICS link properties hw/cpu: core.c can be compiled as common object hw/ppc/spapr: Adjust firmware name for PCI bridges xics: add reset() handler to ICPStateClass pnv_core: drop reference on ICPState object during CPU realization spapr: Rework DRC name handling spapr: Fold spapr_phb_{add,remove}_pci_device() into their only callers spapr: Change DRC attach & detach methods to functions spapr: Clean up handling of DR-indicator spapr: Clean up RTAS set-indicator spapr: Don't misuse DR-indicator in spapr_recover_pending_dimm_state() spapr: Clean up DR entity sense handling pseries: Correct panic behaviour for pseries machine type spapr: fix memory leak in spapr_memory_pre_plug() target/ppc: fix memory leak in kvmppc_is_mem_backend_page_size_ok() target/ppc: pass const string to kvmppc_is_mem_backend_page_size_ok() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9746211baa
|
@ -2,5 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
|
|||
obj-$(CONFIG_REALVIEW) += realview_mpcore.o
|
||||
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
|
||||
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
|
||||
obj-y += core.o
|
||||
|
||||
common-obj-y += core.o
|
||||
|
|
|
@ -38,50 +38,6 @@
|
|||
#include "monitor/monitor.h"
|
||||
#include "hw/intc/intc.h"
|
||||
|
||||
void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
ICPState *icp = ICP(cpu->intc);
|
||||
|
||||
assert(icp);
|
||||
assert(cs == icp->cs);
|
||||
|
||||
icp->output = NULL;
|
||||
icp->cs = NULL;
|
||||
}
|
||||
|
||||
void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
ICPStateClass *icpc;
|
||||
|
||||
assert(icp);
|
||||
|
||||
cpu->intc = OBJECT(icp);
|
||||
icp->cs = cs;
|
||||
|
||||
icpc = ICP_GET_CLASS(icp);
|
||||
if (icpc->cpu_setup) {
|
||||
icpc->cpu_setup(icp, cpu);
|
||||
}
|
||||
|
||||
switch (PPC_INPUT(env)) {
|
||||
case PPC_FLAGS_INPUT_POWER7:
|
||||
icp->output = env->irq_inputs[POWER7_INPUT_INT];
|
||||
break;
|
||||
|
||||
case PPC_FLAGS_INPUT_970:
|
||||
icp->output = env->irq_inputs[PPC970_INPUT_INT];
|
||||
break;
|
||||
|
||||
default:
|
||||
error_report("XICS interrupt controller does not support this CPU "
|
||||
"bus model");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void icp_pic_print_info(ICPState *icp, Monitor *mon)
|
||||
{
|
||||
int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
|
||||
|
@ -325,6 +281,7 @@ static const VMStateDescription vmstate_icp_server = {
|
|||
static void icp_reset(void *dev)
|
||||
{
|
||||
ICPState *icp = ICP(dev);
|
||||
ICPStateClass *icpc = ICP_GET_CLASS(icp);
|
||||
|
||||
icp->xirr = 0;
|
||||
icp->pending_priority = 0xff;
|
||||
|
@ -332,26 +289,58 @@ static void icp_reset(void *dev)
|
|||
|
||||
/* Make all outputs are deasserted */
|
||||
qemu_set_irq(icp->output, 0);
|
||||
|
||||
if (icpc->reset) {
|
||||
icpc->reset(icp);
|
||||
}
|
||||
}
|
||||
|
||||
static void icp_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ICPState *icp = ICP(dev);
|
||||
ICPStateClass *icpc = ICP_GET_CLASS(dev);
|
||||
PowerPCCPU *cpu;
|
||||
CPUPPCState *env;
|
||||
Object *obj;
|
||||
Error *err = NULL;
|
||||
|
||||
obj = object_property_get_link(OBJECT(dev), "xics", &err);
|
||||
obj = object_property_get_link(OBJECT(dev), ICP_PROP_XICS, &err);
|
||||
if (!obj) {
|
||||
error_setg(errp, "%s: required link 'xics' not found: %s",
|
||||
error_setg(errp, "%s: required link '" ICP_PROP_XICS "' not found: %s",
|
||||
__func__, error_get_pretty(err));
|
||||
return;
|
||||
}
|
||||
|
||||
icp->xics = XICS_FABRIC(obj);
|
||||
|
||||
obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
|
||||
if (!obj) {
|
||||
error_setg(errp, "%s: required link '" ICP_PROP_CPU "' not found: %s",
|
||||
__func__, error_get_pretty(err));
|
||||
return;
|
||||
}
|
||||
|
||||
cpu = POWERPC_CPU(obj);
|
||||
cpu->intc = OBJECT(icp);
|
||||
icp->cs = CPU(obj);
|
||||
|
||||
env = &cpu->env;
|
||||
switch (PPC_INPUT(env)) {
|
||||
case PPC_FLAGS_INPUT_POWER7:
|
||||
icp->output = env->irq_inputs[POWER7_INPUT_INT];
|
||||
break;
|
||||
|
||||
case PPC_FLAGS_INPUT_970:
|
||||
icp->output = env->irq_inputs[PPC970_INPUT_INT];
|
||||
break;
|
||||
|
||||
default:
|
||||
error_setg(errp, "XICS interrupt controller does not support this CPU bus model");
|
||||
return;
|
||||
}
|
||||
|
||||
if (icpc->realize) {
|
||||
icpc->realize(dev, errp);
|
||||
icpc->realize(icp, errp);
|
||||
}
|
||||
|
||||
qemu_register_reset(icp_reset, dev);
|
||||
|
@ -601,10 +590,8 @@ static void ics_simple_initfn(Object *obj)
|
|||
ics->offset = XICS_IRQ_BASE;
|
||||
}
|
||||
|
||||
static void ics_simple_realize(DeviceState *dev, Error **errp)
|
||||
static void ics_simple_realize(ICSState *ics, Error **errp)
|
||||
{
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
|
||||
if (!ics->nr_irqs) {
|
||||
error_setg(errp, "Number of interrupts needs to be greater 0");
|
||||
return;
|
||||
|
@ -612,7 +599,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
|
|||
ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
|
||||
ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
|
||||
|
||||
qemu_register_reset(ics_simple_reset, dev);
|
||||
qemu_register_reset(ics_simple_reset, ics);
|
||||
}
|
||||
|
||||
static Property ics_simple_properties[] = {
|
||||
|
@ -649,9 +636,9 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
|
|||
Object *obj;
|
||||
Error *err = NULL;
|
||||
|
||||
obj = object_property_get_link(OBJECT(dev), "xics", &err);
|
||||
obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);
|
||||
if (!obj) {
|
||||
error_setg(errp, "%s: required link 'xics' not found: %s",
|
||||
error_setg(errp, "%s: required link '" ICS_PROP_XICS "' not found: %s",
|
||||
__func__, error_get_pretty(err));
|
||||
return;
|
||||
}
|
||||
|
@ -659,7 +646,7 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
|
||||
if (icsc->realize) {
|
||||
icsc->realize(dev, errp);
|
||||
icsc->realize(ics, errp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,25 +110,14 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void icp_kvm_reset(void *dev)
|
||||
static void icp_kvm_reset(ICPState *icp)
|
||||
{
|
||||
ICPState *icp = ICP(dev);
|
||||
|
||||
icp->xirr = 0;
|
||||
icp->pending_priority = 0xff;
|
||||
icp->mfrr = 0xff;
|
||||
|
||||
/* Make all outputs as deasserted only if the CPU thread is in use */
|
||||
if (icp->output) {
|
||||
qemu_set_irq(icp->output, 0);
|
||||
}
|
||||
|
||||
icp_set_kvm_state(icp, 1);
|
||||
}
|
||||
|
||||
static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)
|
||||
static void icp_kvm_realize(ICPState *icp, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUState *cs = icp->cs;
|
||||
KVMEnabledICP *enabled_icp;
|
||||
unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
|
||||
int ret;
|
||||
|
@ -150,35 +139,23 @@ static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)
|
|||
|
||||
ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_XICS, 0, kernel_xics_fd, vcpu_id);
|
||||
if (ret < 0) {
|
||||
error_report("Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
error_setg(errp, "Unable to connect CPU%ld to kernel XICS: %s", vcpu_id,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
enabled_icp = g_malloc(sizeof(*enabled_icp));
|
||||
enabled_icp->vcpu_id = vcpu_id;
|
||||
QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node);
|
||||
}
|
||||
|
||||
static void icp_kvm_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
qemu_register_reset(icp_kvm_reset, dev);
|
||||
}
|
||||
|
||||
static void icp_kvm_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
qemu_unregister_reset(icp_kvm_reset, dev);
|
||||
}
|
||||
|
||||
static void icp_kvm_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ICPStateClass *icpc = ICP_CLASS(klass);
|
||||
|
||||
dc->realize = icp_kvm_realize;
|
||||
dc->unrealize = icp_kvm_unrealize;
|
||||
icpc->pre_save = icp_get_kvm_state;
|
||||
icpc->post_load = icp_set_kvm_state;
|
||||
icpc->cpu_setup = icp_kvm_cpu_setup;
|
||||
icpc->realize = icp_kvm_realize;
|
||||
icpc->reset = icp_kvm_reset;
|
||||
}
|
||||
|
||||
static const TypeInfo icp_kvm_info = {
|
||||
|
@ -351,10 +328,8 @@ static void ics_kvm_reset(void *dev)
|
|||
ics_set_kvm_state(ics, 1);
|
||||
}
|
||||
|
||||
static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
||||
static void ics_kvm_realize(ICSState *ics, Error **errp)
|
||||
{
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
|
||||
if (!ics->nr_irqs) {
|
||||
error_setg(errp, "Number of interrupts needs to be greater 0");
|
||||
return;
|
||||
|
@ -362,7 +337,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
|||
ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
|
||||
ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);
|
||||
|
||||
qemu_register_reset(ics_kvm_reset, dev);
|
||||
qemu_register_reset(ics_kvm_reset, ics);
|
||||
}
|
||||
|
||||
static void ics_kvm_class_init(ObjectClass *klass, void *data)
|
||||
|
|
|
@ -159,11 +159,11 @@ static const MemoryRegionOps pnv_icp_ops = {
|
|||
},
|
||||
};
|
||||
|
||||
static void pnv_icp_realize(DeviceState *dev, Error **errp)
|
||||
static void pnv_icp_realize(ICPState *icp, Error **errp)
|
||||
{
|
||||
PnvICPState *icp = PNV_ICP(dev);
|
||||
PnvICPState *pnv_icp = PNV_ICP(icp);
|
||||
|
||||
memory_region_init_io(&icp->mmio, OBJECT(dev), &pnv_icp_ops,
|
||||
memory_region_init_io(&pnv_icp->mmio, OBJECT(icp), &pnv_icp_ops,
|
||||
icp, "icp-thread", 0x1000);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,18 +118,20 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
|
|||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
Object *obj;
|
||||
|
||||
obj = object_new(TYPE_PNV_ICP);
|
||||
object_property_add_child(OBJECT(cpu), "icp", obj, NULL);
|
||||
object_property_add_const_link(obj, "xics", OBJECT(xi), &error_abort);
|
||||
object_property_set_bool(obj, true, "realized", &local_err);
|
||||
object_property_set_bool(child, true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
object_property_set_bool(child, true, "realized", &local_err);
|
||||
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);
|
||||
if (local_err) {
|
||||
object_unparent(obj);
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
@ -140,8 +142,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
|
|||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
xics_cpu_setup(xi, cpu, ICP(obj));
|
||||
}
|
||||
|
||||
static void pnv_core_realize(DeviceState *dev, Error **errp)
|
||||
|
|
|
@ -474,7 +474,8 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
|
||||
/* Create PSI interrupt control source */
|
||||
object_property_add_const_link(OBJECT(ics), "xics", obj, &error_abort);
|
||||
object_property_add_const_link(OBJECT(ics), ICS_PROP_XICS, obj,
|
||||
&error_abort);
|
||||
object_property_set_int(OBJECT(ics), PSI_NUM_INTERRUPTS, "nr-irqs", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
|
|
|
@ -107,7 +107,8 @@ static ICSState *spapr_ics_create(sPAPRMachineState *spapr,
|
|||
|
||||
obj = object_new(type_ics);
|
||||
object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort);
|
||||
object_property_add_const_link(obj, "xics", OBJECT(spapr), &error_abort);
|
||||
object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr),
|
||||
&error_abort);
|
||||
object_property_set_int(obj, nr_irqs, "nr-irqs", &local_err);
|
||||
if (local_err) {
|
||||
goto error;
|
||||
|
@ -2441,6 +2442,12 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
|
|||
return g_strdup_printf("disk@%"PRIX64, (uint64_t)id << 32);
|
||||
}
|
||||
|
||||
if (g_str_equal("pci-bridge", qdev_fw_name(dev))) {
|
||||
/* SLOF uses "pci" instead of "pci-bridge" for PCI bridges */
|
||||
PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
|
||||
return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2523,7 +2530,6 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
|
|||
Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE;
|
||||
int i, fdt_offset, fdt_size;
|
||||
void *fdt;
|
||||
|
@ -2538,10 +2544,10 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
|
|||
fdt_offset = spapr_populate_memory_node(fdt, node, addr,
|
||||
SPAPR_MEMORY_BLOCK_SIZE);
|
||||
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp);
|
||||
spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp);
|
||||
addr += SPAPR_MEMORY_BLOCK_SIZE;
|
||||
if (!dev->hotplugged) {
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
/* guests expect coldplugged LMBs to be pre-allocated */
|
||||
drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE);
|
||||
drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED);
|
||||
|
@ -2554,7 +2560,6 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
|
|||
if (dedicated_hp_event_source) {
|
||||
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
|
||||
addr_start / SPAPR_MEMORY_BLOCK_SIZE);
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
|
||||
nr_lmbs,
|
||||
spapr_drc_index(drc));
|
||||
|
@ -2615,8 +2620,11 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
if (mem_dev && !kvmppc_is_mem_backend_page_size_ok(mem_dev)) {
|
||||
error_setg(errp, "Memory backend has bad page size. "
|
||||
"Use 'memory-backend-file' with correct mem-path.");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
g_free(mem_dev);
|
||||
}
|
||||
|
||||
struct sPAPRDIMMState {
|
||||
|
@ -2673,7 +2681,7 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
|
|||
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
|
||||
addr / SPAPR_MEMORY_BLOCK_SIZE);
|
||||
g_assert(drc);
|
||||
if (drc->indicator_state != SPAPR_DR_INDICATOR_STATE_INACTIVE) {
|
||||
if (drc->dev) {
|
||||
avail_lmbs++;
|
||||
}
|
||||
addr += SPAPR_MEMORY_BLOCK_SIZE;
|
||||
|
@ -2697,10 +2705,11 @@ void spapr_lmb_release(DeviceState *dev)
|
|||
* during the unplug process. In this case recover it. */
|
||||
if (ds == NULL) {
|
||||
ds = spapr_recover_pending_dimm_state(spapr, PC_DIMM(dev));
|
||||
if (ds->nr_lmbs) {
|
||||
return;
|
||||
}
|
||||
} else if (--ds->nr_lmbs) {
|
||||
/* The DRC being examined by the caller at least must be counted */
|
||||
g_assert(ds->nr_lmbs);
|
||||
}
|
||||
|
||||
if (--ds->nr_lmbs) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2738,7 +2747,6 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
|
|||
uint64_t addr_start, addr;
|
||||
int i;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
sPAPRDIMMState *ds;
|
||||
|
||||
addr_start = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP,
|
||||
|
@ -2758,14 +2766,12 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
|
|||
addr / SPAPR_MEMORY_BLOCK_SIZE);
|
||||
g_assert(drc);
|
||||
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
drck->detach(drc, dev, errp);
|
||||
spapr_drc_detach(drc, dev, errp);
|
||||
addr += SPAPR_MEMORY_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,
|
||||
addr_start / SPAPR_MEMORY_BLOCK_SIZE);
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,
|
||||
nr_lmbs, spapr_drc_index(drc));
|
||||
out:
|
||||
|
@ -2820,7 +2826,6 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
{
|
||||
int index;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
Error *local_err = NULL;
|
||||
CPUCore *cc = CPU_CORE(dev);
|
||||
int smt = kvmppc_smt_threads();
|
||||
|
@ -2838,8 +2843,7 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU, index * smt);
|
||||
g_assert(drc);
|
||||
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
drck->detach(drc, dev, &local_err);
|
||||
spapr_drc_detach(drc, dev, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
|
@ -2883,8 +2887,8 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
}
|
||||
|
||||
if (drc) {
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, &local_err);
|
||||
spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
g_free(fdt);
|
||||
error_propagate(errp, local_err);
|
||||
|
|
|
@ -53,9 +53,6 @@ static void spapr_cpu_reset(void *opaque)
|
|||
|
||||
static void spapr_cpu_destroy(PowerPCCPU *cpu)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
|
||||
xics_cpu_destroy(XICS_FABRIC(spapr), cpu);
|
||||
qemu_unregister_reset(spapr_cpu_reset, cpu);
|
||||
}
|
||||
|
||||
|
@ -140,16 +137,7 @@ static void spapr_cpu_core_realize_child(Object *child, Error **errp)
|
|||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
CPUState *cs = CPU(child);
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
Object *obj;
|
||||
|
||||
obj = object_new(spapr->icp_type);
|
||||
object_property_add_child(OBJECT(cpu), "icp", obj, &error_abort);
|
||||
object_unref(obj);
|
||||
object_property_add_const_link(obj, "xics", OBJECT(spapr), &error_abort);
|
||||
object_property_set_bool(obj, true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
goto error;
|
||||
}
|
||||
Object *obj = NULL;
|
||||
|
||||
object_property_set_bool(child, true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
|
@ -161,7 +149,17 @@ static void spapr_cpu_core_realize_child(Object *child, Error **errp)
|
|||
goto error;
|
||||
}
|
||||
|
||||
xics_cpu_setup(XICS_FABRIC(spapr), cpu, ICP(obj));
|
||||
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);
|
||||
if (local_err) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
|
|
|
@ -49,8 +49,6 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
|
|||
static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
||||
sPAPRDRIsolationState state)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
|
||||
|
||||
/* if the guest is configuring a device attached to this DRC, we
|
||||
|
@ -105,7 +103,7 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
|||
uint32_t drc_index = spapr_drc_index(drc);
|
||||
if (drc->configured) {
|
||||
trace_spapr_drc_set_isolation_state_finalizing(drc_index);
|
||||
drck->detach(drc, DEVICE(drc->dev), NULL);
|
||||
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
|
||||
} else {
|
||||
trace_spapr_drc_set_isolation_state_deferring(drc_index);
|
||||
}
|
||||
|
@ -116,19 +114,9 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
|||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t set_indicator_state(sPAPRDRConnector *drc,
|
||||
sPAPRDRIndicatorState state)
|
||||
{
|
||||
trace_spapr_drc_set_indicator_state(spapr_drc_index(drc), state);
|
||||
drc->indicator_state = state;
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
||||
sPAPRDRAllocationState state)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
trace_spapr_drc_set_allocation_state(spapr_drc_index(drc), state);
|
||||
|
||||
if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
||||
|
@ -140,17 +128,6 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
|||
if (!drc->dev) {
|
||||
return RTAS_OUT_NO_SUCH_INDICATOR;
|
||||
}
|
||||
if (drc->awaiting_release && drc->awaiting_allocation) {
|
||||
/* kernel is acknowledging a previous hotplug event
|
||||
* while we are already removing it.
|
||||
* it's safe to ignore awaiting_allocation here since we know the
|
||||
* situation is predicated on the guest either already having done
|
||||
* so (boot-time hotplug), or never being able to acquire in the
|
||||
* first place (hotplug followed by immediate unplug).
|
||||
*/
|
||||
drc->awaiting_allocation_skippable = true;
|
||||
return RTAS_OUT_NO_SUCH_INDICATOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
|
||||
|
@ -159,7 +136,7 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
|||
drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
|
||||
uint32_t drc_index = spapr_drc_index(drc);
|
||||
trace_spapr_drc_set_allocation_state_finalizing(drc_index);
|
||||
drck->detach(drc, DEVICE(drc->dev), NULL);
|
||||
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
|
||||
} else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
||||
drc->awaiting_allocation = false;
|
||||
}
|
||||
|
@ -167,9 +144,32 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
|||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static const char *get_name(sPAPRDRConnector *drc)
|
||||
static const char *spapr_drc_name(sPAPRDRConnector *drc)
|
||||
{
|
||||
return drc->name;
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
/* human-readable name for a DRC to encode into the DT
|
||||
* description. this is mainly only used within a guest in place
|
||||
* of the unique DRC index.
|
||||
*
|
||||
* in the case of VIO/PCI devices, it corresponds to a "location
|
||||
* code" that maps a logical device/function (DRC index) to a
|
||||
* physical (or virtual in the case of VIO) location in the system
|
||||
* by chaining together the "location label" for each
|
||||
* encapsulating component.
|
||||
*
|
||||
* since this is more to do with diagnosing physical hardware
|
||||
* issues than guest compatibility, we choose location codes/DRC
|
||||
* names that adhere to the documented format, but avoid encoding
|
||||
* the entire topology information into the label/code, instead
|
||||
* just using the location codes based on the labels for the
|
||||
* endpoints (VIO/PCI adaptor connectors), which is basically just
|
||||
* "C" followed by an integer ID.
|
||||
*
|
||||
* DRC names as documented by PAPR+ v2.7, 13.5.2.4
|
||||
* location codes as documented by PAPR+ v2.7, 12.3.1.5
|
||||
*/
|
||||
return g_strdup_printf("%s%d", drck->drc_name_prefix, drc->id);
|
||||
}
|
||||
|
||||
/* has the guest been notified of device attachment? */
|
||||
|
@ -185,39 +185,25 @@ static void set_signalled(sPAPRDRConnector *drc)
|
|||
* based on the current allocation/indicator/power states
|
||||
* for the DR connector.
|
||||
*/
|
||||
static uint32_t entity_sense(sPAPRDRConnector *drc, sPAPRDREntitySense *state)
|
||||
static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
|
||||
{
|
||||
if (drc->dev) {
|
||||
if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&
|
||||
drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
|
||||
/* for logical DR, we return a state of UNUSABLE
|
||||
* iff the allocation state UNUSABLE.
|
||||
* Otherwise, report the state as USABLE/PRESENT,
|
||||
* as we would for PCI.
|
||||
*/
|
||||
*state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
|
||||
} else {
|
||||
/* this assumes all PCI devices are assigned to
|
||||
* a 'live insertion' power domain, where QEMU
|
||||
* manages power state automatically as opposed
|
||||
* to the guest. present, non-PCI resources are
|
||||
* unaffected by power state.
|
||||
*/
|
||||
*state = SPAPR_DR_ENTITY_SENSE_PRESENT;
|
||||
}
|
||||
} else {
|
||||
if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
|
||||
/* PCI devices, and only PCI devices, use EMPTY
|
||||
* in cases where we'd otherwise use UNUSABLE
|
||||
*/
|
||||
*state = SPAPR_DR_ENTITY_SENSE_EMPTY;
|
||||
} else {
|
||||
*state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
|
||||
}
|
||||
}
|
||||
/* this assumes all PCI devices are assigned to a 'live insertion'
|
||||
* power domain, where QEMU manages power state automatically as
|
||||
* opposed to the guest. present, non-PCI resources are unaffected
|
||||
* by power state.
|
||||
*/
|
||||
return drc->dev ? SPAPR_DR_ENTITY_SENSE_PRESENT
|
||||
: SPAPR_DR_ENTITY_SENSE_EMPTY;
|
||||
}
|
||||
|
||||
trace_spapr_drc_entity_sense(spapr_drc_index(drc), *state);
|
||||
return RTAS_OUT_SUCCESS;
|
||||
static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
|
||||
{
|
||||
if (drc->dev
|
||||
&& (drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE)) {
|
||||
return SPAPR_DR_ENTITY_SENSE_PRESENT;
|
||||
} else {
|
||||
return SPAPR_DR_ENTITY_SENSE_UNUSABLE;
|
||||
}
|
||||
}
|
||||
|
||||
static void prop_get_index(Object *obj, Visitor *v, const char *name,
|
||||
|
@ -228,13 +214,6 @@ static void prop_get_index(Object *obj, Visitor *v, const char *name,
|
|||
visit_type_uint32(v, name, &value, errp);
|
||||
}
|
||||
|
||||
static char *prop_get_name(Object *obj, Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
return g_strdup(drck->get_name(drc));
|
||||
}
|
||||
|
||||
static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
|
@ -311,8 +290,8 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
|
|||
} while (fdt_depth != 0);
|
||||
}
|
||||
|
||||
static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, bool coldplug, Error **errp)
|
||||
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, bool coldplug, Error **errp)
|
||||
{
|
||||
trace_spapr_drc_attach(spapr_drc_index(drc));
|
||||
|
||||
|
@ -335,7 +314,7 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
|||
if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
|
||||
drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
|
||||
}
|
||||
drc->indicator_state = SPAPR_DR_INDICATOR_STATE_ACTIVE;
|
||||
drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
|
||||
|
||||
drc->dev = d;
|
||||
drc->fdt = fdt;
|
||||
|
@ -363,7 +342,7 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
|||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static void detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
||||
void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
||||
{
|
||||
trace_spapr_drc_detach(spapr_drc_index(drc));
|
||||
|
||||
|
@ -401,14 +380,12 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
|||
}
|
||||
|
||||
if (drc->awaiting_allocation) {
|
||||
if (!drc->awaiting_allocation_skippable) {
|
||||
drc->awaiting_release = true;
|
||||
trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));
|
||||
return;
|
||||
}
|
||||
drc->awaiting_release = true;
|
||||
trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));
|
||||
return;
|
||||
}
|
||||
|
||||
drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE;
|
||||
drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;
|
||||
|
||||
/* Calling release callbacks based on spapr_drc_type(drc). */
|
||||
switch (spapr_drc_type(drc)) {
|
||||
|
@ -428,7 +405,6 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
|||
}
|
||||
|
||||
drc->awaiting_release = false;
|
||||
drc->awaiting_allocation_skippable = false;
|
||||
g_free(drc->fdt);
|
||||
drc->fdt = NULL;
|
||||
drc->fdt_start_offset = 0;
|
||||
|
@ -445,7 +421,6 @@ static void reset(DeviceState *d)
|
|||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
sPAPRDREntitySense state;
|
||||
|
||||
trace_spapr_drc_reset(spapr_drc_index(drc));
|
||||
|
||||
|
@ -467,7 +442,7 @@ static void reset(DeviceState *d)
|
|||
* force removal if we are
|
||||
*/
|
||||
if (drc->awaiting_release) {
|
||||
drck->detach(drc, DEVICE(drc->dev), NULL);
|
||||
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
|
||||
}
|
||||
|
||||
/* non-PCI devices may be awaiting a transition to UNUSABLE */
|
||||
|
@ -477,8 +452,7 @@ static void reset(DeviceState *d)
|
|||
}
|
||||
}
|
||||
|
||||
drck->entity_sense(drc, &state);
|
||||
if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||
if (drck->dr_entity_sense(drc) == SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||
drck->set_signalled(drc);
|
||||
}
|
||||
}
|
||||
|
@ -488,8 +462,7 @@ static bool spapr_drc_needed(void *opaque)
|
|||
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
bool rc = false;
|
||||
sPAPRDREntitySense value;
|
||||
drck->entity_sense(drc, &value);
|
||||
sPAPRDREntitySense value = drck->dr_entity_sense(drc);
|
||||
|
||||
/* If no dev is plugged in there is no need to migrate the DRC state */
|
||||
if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||
|
@ -524,7 +497,7 @@ static const VMStateDescription vmstate_spapr_drc = {
|
|||
.fields = (VMStateField []) {
|
||||
VMSTATE_UINT32(isolation_state, sPAPRDRConnector),
|
||||
VMSTATE_UINT32(allocation_state, sPAPRDRConnector),
|
||||
VMSTATE_UINT32(indicator_state, sPAPRDRConnector),
|
||||
VMSTATE_UINT32(dr_indicator, sPAPRDRConnector),
|
||||
VMSTATE_BOOL(configured, sPAPRDRConnector),
|
||||
VMSTATE_BOOL(awaiting_release, sPAPRDRConnector),
|
||||
VMSTATE_BOOL(awaiting_allocation, sPAPRDRConnector),
|
||||
|
@ -596,45 +569,6 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
|
|||
object_property_set_bool(OBJECT(drc), true, "realized", NULL);
|
||||
g_free(prop_name);
|
||||
|
||||
/* human-readable name for a DRC to encode into the DT
|
||||
* description. this is mainly only used within a guest in place
|
||||
* of the unique DRC index.
|
||||
*
|
||||
* in the case of VIO/PCI devices, it corresponds to a
|
||||
* "location code" that maps a logical device/function (DRC index)
|
||||
* to a physical (or virtual in the case of VIO) location in the
|
||||
* system by chaining together the "location label" for each
|
||||
* encapsulating component.
|
||||
*
|
||||
* since this is more to do with diagnosing physical hardware
|
||||
* issues than guest compatibility, we choose location codes/DRC
|
||||
* names that adhere to the documented format, but avoid encoding
|
||||
* the entire topology information into the label/code, instead
|
||||
* just using the location codes based on the labels for the
|
||||
* endpoints (VIO/PCI adaptor connectors), which is basically
|
||||
* just "C" followed by an integer ID.
|
||||
*
|
||||
* DRC names as documented by PAPR+ v2.7, 13.5.2.4
|
||||
* location codes as documented by PAPR+ v2.7, 12.3.1.5
|
||||
*/
|
||||
switch (spapr_drc_type(drc)) {
|
||||
case SPAPR_DR_CONNECTOR_TYPE_CPU:
|
||||
drc->name = g_strdup_printf("CPU %d", id);
|
||||
break;
|
||||
case SPAPR_DR_CONNECTOR_TYPE_PHB:
|
||||
drc->name = g_strdup_printf("PHB %d", id);
|
||||
break;
|
||||
case SPAPR_DR_CONNECTOR_TYPE_VIO:
|
||||
case SPAPR_DR_CONNECTOR_TYPE_PCI:
|
||||
drc->name = g_strdup_printf("C%d", id);
|
||||
break;
|
||||
case SPAPR_DR_CONNECTOR_TYPE_LMB:
|
||||
drc->name = g_strdup_printf("LMB %d", id);
|
||||
break;
|
||||
default:
|
||||
g_assert(false);
|
||||
}
|
||||
|
||||
/* PCI slot always start in a USABLE state, and stay there */
|
||||
if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
|
||||
drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
|
||||
|
@ -650,7 +584,6 @@ static void spapr_dr_connector_instance_init(Object *obj)
|
|||
object_property_add_uint32_ptr(obj, "id", &drc->id, NULL);
|
||||
object_property_add(obj, "index", "uint32", prop_get_index,
|
||||
NULL, NULL, NULL, NULL);
|
||||
object_property_add_str(obj, "name", prop_get_name, NULL, NULL);
|
||||
object_property_add(obj, "fdt", "struct", prop_get_fdt,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -664,12 +597,7 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
|
|||
dk->realize = realize;
|
||||
dk->unrealize = unrealize;
|
||||
drck->set_isolation_state = set_isolation_state;
|
||||
drck->set_indicator_state = set_indicator_state;
|
||||
drck->set_allocation_state = set_allocation_state;
|
||||
drck->get_name = get_name;
|
||||
drck->entity_sense = entity_sense;
|
||||
drck->attach = attach;
|
||||
drck->detach = detach;
|
||||
drck->release_pending = release_pending;
|
||||
drck->set_signalled = set_signalled;
|
||||
/*
|
||||
|
@ -678,12 +606,27 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
|
|||
dk->user_creatable = false;
|
||||
}
|
||||
|
||||
static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->dr_entity_sense = physical_entity_sense;
|
||||
}
|
||||
|
||||
static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->dr_entity_sense = logical_entity_sense;
|
||||
}
|
||||
|
||||
static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
|
||||
drck->typename = "CPU";
|
||||
drck->drc_name_prefix = "CPU ";
|
||||
}
|
||||
|
||||
static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
|
||||
|
@ -692,6 +635,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
|
|||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
|
||||
drck->typename = "28";
|
||||
drck->drc_name_prefix = "C";
|
||||
}
|
||||
|
||||
static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
|
||||
|
@ -700,6 +644,7 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
|
|||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
|
||||
drck->typename = "MEM";
|
||||
drck->drc_name_prefix = "LMB ";
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_dr_connector_info = {
|
||||
|
@ -716,6 +661,7 @@ static const TypeInfo spapr_drc_physical_info = {
|
|||
.name = TYPE_SPAPR_DRC_PHYSICAL,
|
||||
.parent = TYPE_SPAPR_DR_CONNECTOR,
|
||||
.instance_size = sizeof(sPAPRDRConnector),
|
||||
.class_init = spapr_drc_physical_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
|
@ -723,6 +669,7 @@ static const TypeInfo spapr_drc_logical_info = {
|
|||
.name = TYPE_SPAPR_DRC_LOGICAL,
|
||||
.parent = TYPE_SPAPR_DR_CONNECTOR,
|
||||
.instance_size = sizeof(sPAPRDRConnector),
|
||||
.class_init = spapr_drc_logical_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
|
@ -846,7 +793,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
|||
g_array_append_val(drc_power_domains, drc_power_domain);
|
||||
|
||||
/* ibm,drc-names */
|
||||
drc_names = g_string_append(drc_names, drck->get_name(drc));
|
||||
drc_names = g_string_append(drc_names, spapr_drc_name(drc));
|
||||
drc_names = g_string_insert_len(drc_names, -1, "\0", 1);
|
||||
|
||||
/* ibm,drc-types */
|
||||
|
@ -905,74 +852,78 @@ out:
|
|||
* RTAS calls
|
||||
*/
|
||||
|
||||
static bool sensor_type_is_dr(uint32_t sensor_type)
|
||||
static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
|
||||
{
|
||||
switch (sensor_type) {
|
||||
case RTAS_SENSOR_TYPE_ISOLATION_STATE:
|
||||
case RTAS_SENSOR_TYPE_DR:
|
||||
case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
|
||||
return true;
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
sPAPRDRConnectorClass *drck;
|
||||
|
||||
if (!drc) {
|
||||
return RTAS_OUT_PARAM_ERROR;
|
||||
}
|
||||
|
||||
return false;
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
return drck->set_isolation_state(drc, state);
|
||||
}
|
||||
|
||||
static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
sPAPRDRConnectorClass *drck;
|
||||
|
||||
if (!drc) {
|
||||
return RTAS_OUT_PARAM_ERROR;
|
||||
}
|
||||
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
return drck->set_allocation_state(drc, state);
|
||||
}
|
||||
|
||||
static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
|
||||
if (!drc) {
|
||||
return RTAS_OUT_PARAM_ERROR;
|
||||
}
|
||||
|
||||
trace_spapr_drc_set_dr_indicator(idx, state);
|
||||
drc->dr_indicator = state;
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
uint32_t sensor_type;
|
||||
uint32_t sensor_index;
|
||||
uint32_t sensor_state;
|
||||
uint32_t type, idx, state;
|
||||
uint32_t ret = RTAS_OUT_SUCCESS;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
|
||||
if (nargs != 3 || nret != 1) {
|
||||
ret = RTAS_OUT_PARAM_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sensor_type = rtas_ld(args, 0);
|
||||
sensor_index = rtas_ld(args, 1);
|
||||
sensor_state = rtas_ld(args, 2);
|
||||
type = rtas_ld(args, 0);
|
||||
idx = rtas_ld(args, 1);
|
||||
state = rtas_ld(args, 2);
|
||||
|
||||
if (!sensor_type_is_dr(sensor_type)) {
|
||||
goto out_unimplemented;
|
||||
}
|
||||
|
||||
/* if this is a DR sensor we can assume sensor_index == drc_index */
|
||||
drc = spapr_drc_by_index(sensor_index);
|
||||
if (!drc) {
|
||||
trace_spapr_rtas_set_indicator_invalid(sensor_index);
|
||||
ret = RTAS_OUT_PARAM_ERROR;
|
||||
goto out;
|
||||
}
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
switch (sensor_type) {
|
||||
switch (type) {
|
||||
case RTAS_SENSOR_TYPE_ISOLATION_STATE:
|
||||
ret = drck->set_isolation_state(drc, sensor_state);
|
||||
ret = rtas_set_isolation_state(idx, state);
|
||||
break;
|
||||
case RTAS_SENSOR_TYPE_DR:
|
||||
ret = drck->set_indicator_state(drc, sensor_state);
|
||||
ret = rtas_set_dr_indicator(idx, state);
|
||||
break;
|
||||
case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
|
||||
ret = drck->set_allocation_state(drc, sensor_state);
|
||||
ret = rtas_set_allocation_state(idx, state);
|
||||
break;
|
||||
default:
|
||||
goto out_unimplemented;
|
||||
ret = RTAS_OUT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
out:
|
||||
rtas_st(rets, 0, ret);
|
||||
return;
|
||||
|
||||
out_unimplemented:
|
||||
/* currently only DR-related sensors are implemented */
|
||||
trace_spapr_rtas_set_indicator_not_supported(sensor_index, sensor_type);
|
||||
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
@ -1010,7 +961,7 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
|||
goto out;
|
||||
}
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
ret = drck->entity_sense(drc, &sensor_state);
|
||||
sensor_state = drck->dr_entity_sense(drc);
|
||||
|
||||
out:
|
||||
rtas_st(rets, 0, ret);
|
||||
|
|
|
@ -1344,31 +1344,6 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
|
|||
return offset;
|
||||
}
|
||||
|
||||
static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,
|
||||
sPAPRPHBState *phb,
|
||||
PCIDevice *pdev,
|
||||
Error **errp)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
DeviceState *dev = DEVICE(pdev);
|
||||
void *fdt = NULL;
|
||||
int fdt_start_offset = 0, fdt_size;
|
||||
|
||||
fdt = create_device_tree(&fdt_size);
|
||||
fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
|
||||
if (!fdt_start_offset) {
|
||||
error_setg(errp, "Failed to create pci child device tree node");
|
||||
goto out;
|
||||
}
|
||||
|
||||
drck->attach(drc, DEVICE(pdev),
|
||||
fdt, fdt_start_offset, !dev->hotplugged, errp);
|
||||
out:
|
||||
if (*errp) {
|
||||
g_free(fdt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback to be called during DRC release. */
|
||||
void spapr_phb_remove_pci_device_cb(DeviceState *dev)
|
||||
{
|
||||
|
@ -1386,16 +1361,6 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)
|
|||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void spapr_phb_remove_pci_device(sPAPRDRConnector *drc,
|
||||
sPAPRPHBState *phb,
|
||||
PCIDevice *pdev,
|
||||
Error **errp)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
drck->detach(drc, DEVICE(pdev), errp);
|
||||
}
|
||||
|
||||
static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
|
||||
uint32_t busnr,
|
||||
int32_t devfn)
|
||||
|
@ -1432,6 +1397,8 @@ static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
|
|||
Error *local_err = NULL;
|
||||
PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
|
||||
uint32_t slotnr = PCI_SLOT(pdev->devfn);
|
||||
void *fdt = NULL;
|
||||
int fdt_start_offset, fdt_size;
|
||||
|
||||
/* if DR is disabled we don't need to do anything in the case of
|
||||
* hotplug or coldplug callbacks
|
||||
|
@ -1441,10 +1408,10 @@ static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
|
|||
* we need to let them know it's not enabled
|
||||
*/
|
||||
if (plugged_dev->hotplugged) {
|
||||
error_setg(errp, QERR_BUS_NO_HOTPLUG,
|
||||
error_setg(&local_err, QERR_BUS_NO_HOTPLUG,
|
||||
object_get_typename(OBJECT(phb)));
|
||||
}
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_assert(drc);
|
||||
|
@ -1455,16 +1422,23 @@ static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
|
|||
*/
|
||||
if (plugged_dev->hotplugged && bus->devices[PCI_DEVFN(slotnr, 0)] &&
|
||||
PCI_FUNC(pdev->devfn) != 0) {
|
||||
error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
|
||||
error_setg(&local_err, "PCI: slot %d function 0 already ocuppied by %s,"
|
||||
" additional functions can no longer be exposed to guest.",
|
||||
slotnr, bus->devices[PCI_DEVFN(slotnr, 0)]->name);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
spapr_phb_add_pci_device(drc, phb, pdev, &local_err);
|
||||
fdt = create_device_tree(&fdt_size);
|
||||
fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0);
|
||||
if (!fdt_start_offset) {
|
||||
error_setg(&local_err, "Failed to create pci child device tree node");
|
||||
goto out;
|
||||
}
|
||||
|
||||
spapr_drc_attach(drc, DEVICE(pdev), fdt, fdt_start_offset,
|
||||
!plugged_dev->hotplugged, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If this is function 0, signal hotplug for all the device functions.
|
||||
|
@ -1481,13 +1455,19 @@ static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler,
|
|||
func_drc = spapr_phb_get_pci_func_drc(phb, pci_bus_num(bus),
|
||||
PCI_DEVFN(slotnr, i));
|
||||
func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
|
||||
func_drck->entity_sense(func_drc, &state);
|
||||
state = func_drck->dr_entity_sense(func_drc);
|
||||
|
||||
if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||
spapr_hotplug_req_add_by_index(func_drc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
g_free(fdt);
|
||||
}
|
||||
}
|
||||
|
||||
static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
|
||||
|
@ -1522,7 +1502,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
|
|||
func_drc = spapr_phb_get_pci_func_drc(phb, pci_bus_num(bus),
|
||||
PCI_DEVFN(slotnr, i));
|
||||
func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
|
||||
func_drck->entity_sense(func_drc, &state);
|
||||
state = func_drck->dr_entity_sense(func_drc);
|
||||
if (state == SPAPR_DR_ENTITY_SENSE_PRESENT
|
||||
&& !func_drck->release_pending(func_drc)) {
|
||||
error_setg(errp,
|
||||
|
@ -1534,7 +1514,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
|
|||
}
|
||||
}
|
||||
|
||||
spapr_phb_remove_pci_device(drc, phb, pdev, &local_err);
|
||||
spapr_drc_detach(drc, DEVICE(pdev), &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
|
@ -1548,7 +1528,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
|
|||
func_drc = spapr_phb_get_pci_func_drc(phb, pci_bus_num(bus),
|
||||
PCI_DEVFN(slotnr, i));
|
||||
func_drck = SPAPR_DR_CONNECTOR_GET_CLASS(func_drc);
|
||||
func_drck->entity_sense(func_drc, &state);
|
||||
state = func_drck->dr_entity_sense(func_drc);
|
||||
if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||
spapr_hotplug_req_remove_by_index(func_drc);
|
||||
}
|
||||
|
|
|
@ -293,12 +293,9 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
|
|||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
target_ulong ret = 0;
|
||||
qemu_system_guest_panicked(NULL);
|
||||
|
||||
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, false, NULL,
|
||||
&error_abort);
|
||||
|
||||
rtas_st(rets, 0, ret);
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
|
|
@ -39,12 +39,11 @@ spapr_iommu_ddw_reset(uint64_t buid, uint32_t cfgaddr) "buid=%"PRIx64" addr=%"PR
|
|||
spapr_drc_set_isolation_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: %"PRIx32
|
||||
spapr_drc_set_isolation_state_finalizing(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_isolation_state_deferring(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_indicator_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_set_dr_indicator(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_set_allocation_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_set_allocation_state_finalizing(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_configured(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_configured_skipping(uint32_t index) "drc: 0x%"PRIx32", isolated device"
|
||||
spapr_drc_entity_sense(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_attach(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_detach(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_awaiting_isolated(uint32_t index) "drc: 0x%"PRIx32
|
||||
|
@ -61,8 +60,6 @@ spapr_ovec_parse_vector(int vector, int byte, uint16_t vec_len, uint8_t entry) "
|
|||
spapr_ovec_populate_dt(int byte, uint16_t vec_len, uint8_t entry) "encoding guest vector byte %3d / %3d: 0x%.2x"
|
||||
|
||||
# hw/ppc/spapr_rtas.c
|
||||
spapr_rtas_set_indicator_invalid(uint32_t index) "sensor index: 0x%"PRIx32
|
||||
spapr_rtas_set_indicator_not_supported(uint32_t index, uint32_t type) "sensor index: 0x%"PRIx32", type: %"PRIu32
|
||||
spapr_rtas_get_sensor_state_not_supported(uint32_t index, uint32_t type) "sensor index: 0x%"PRIx32", type: %"PRIu32
|
||||
spapr_rtas_get_sensor_state_invalid(uint32_t index) "sensor index: 0x%"PRIx32
|
||||
spapr_rtas_ibm_configure_connector_invalid(uint32_t index) "DRC index: 0x%"PRIx32
|
||||
|
|
|
@ -125,7 +125,7 @@ typedef enum {
|
|||
} sPAPRDRAllocationState;
|
||||
|
||||
/*
|
||||
* LED/visual indicator state
|
||||
* DR-indicator (LED/visual indicator)
|
||||
*
|
||||
* set via set-indicator RTAS calls
|
||||
* as documented by PAPR+ 2.7 13.5.3.4, Table 177,
|
||||
|
@ -137,10 +137,10 @@ typedef enum {
|
|||
* action: (currently unused)
|
||||
*/
|
||||
typedef enum {
|
||||
SPAPR_DR_INDICATOR_STATE_INACTIVE = 0,
|
||||
SPAPR_DR_INDICATOR_STATE_ACTIVE = 1,
|
||||
SPAPR_DR_INDICATOR_STATE_IDENTIFY = 2,
|
||||
SPAPR_DR_INDICATOR_STATE_ACTION = 3,
|
||||
SPAPR_DR_INDICATOR_INACTIVE = 0,
|
||||
SPAPR_DR_INDICATOR_ACTIVE = 1,
|
||||
SPAPR_DR_INDICATOR_IDENTIFY = 2,
|
||||
SPAPR_DR_INDICATOR_ACTION = 3,
|
||||
} sPAPRDRIndicatorState;
|
||||
|
||||
/*
|
||||
|
@ -184,12 +184,13 @@ typedef struct sPAPRDRConnector {
|
|||
|
||||
uint32_t id;
|
||||
Object *owner;
|
||||
const char *name;
|
||||
|
||||
/* DR-indicator */
|
||||
uint32_t dr_indicator;
|
||||
|
||||
/* sensor/indicator states */
|
||||
uint32_t isolation_state;
|
||||
uint32_t allocation_state;
|
||||
uint32_t indicator_state;
|
||||
|
||||
/* configure-connector state */
|
||||
void *fdt;
|
||||
|
@ -200,7 +201,6 @@ typedef struct sPAPRDRConnector {
|
|||
bool awaiting_release;
|
||||
bool signalled;
|
||||
bool awaiting_allocation;
|
||||
bool awaiting_allocation_skippable;
|
||||
|
||||
/* device pointer, via link property */
|
||||
DeviceState *dev;
|
||||
|
@ -213,22 +213,17 @@ typedef struct sPAPRDRConnectorClass {
|
|||
/*< public >*/
|
||||
sPAPRDRConnectorTypeShift typeshift;
|
||||
const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */
|
||||
const char *drc_name_prefix; /* used other places in device tree */
|
||||
|
||||
sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
|
||||
|
||||
/* accessors for guest-visible (generally via RTAS) DR state */
|
||||
uint32_t (*set_isolation_state)(sPAPRDRConnector *drc,
|
||||
sPAPRDRIsolationState state);
|
||||
uint32_t (*set_indicator_state)(sPAPRDRConnector *drc,
|
||||
sPAPRDRIndicatorState state);
|
||||
uint32_t (*set_allocation_state)(sPAPRDRConnector *drc,
|
||||
sPAPRDRAllocationState state);
|
||||
const char *(*get_name)(sPAPRDRConnector *drc);
|
||||
|
||||
uint32_t (*entity_sense)(sPAPRDRConnector *drc, sPAPRDREntitySense *state);
|
||||
|
||||
/* QEMU interfaces for managing hotplug operations */
|
||||
void (*attach)(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, bool coldplug, Error **errp);
|
||||
void (*detach)(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
|
||||
bool (*release_pending)(sPAPRDRConnector *drc);
|
||||
void (*set_signalled)(sPAPRDRConnector *drc);
|
||||
} sPAPRDRConnectorClass;
|
||||
|
@ -243,4 +238,8 @@ sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id);
|
|||
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
||||
uint32_t drc_type_mask);
|
||||
|
||||
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, bool coldplug, Error **errp);
|
||||
void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
|
||||
|
||||
#endif /* HW_SPAPR_DRC_H */
|
||||
|
|
|
@ -65,10 +65,10 @@ typedef struct XICSFabric XICSFabric;
|
|||
struct ICPStateClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
void (*realize)(DeviceState *dev, Error **errp);
|
||||
void (*pre_save)(ICPState *s);
|
||||
int (*post_load)(ICPState *s, int version_id);
|
||||
void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu);
|
||||
void (*realize)(ICPState *icp, Error **errp);
|
||||
void (*pre_save)(ICPState *icp);
|
||||
int (*post_load)(ICPState *icp, int version_id);
|
||||
void (*reset)(ICPState *icp);
|
||||
};
|
||||
|
||||
struct ICPState {
|
||||
|
@ -85,6 +85,9 @@ struct ICPState {
|
|||
XICSFabric *xics;
|
||||
};
|
||||
|
||||
#define ICP_PROP_XICS "xics"
|
||||
#define ICP_PROP_CPU "cpu"
|
||||
|
||||
struct PnvICPState {
|
||||
ICPState parent_obj;
|
||||
|
||||
|
@ -110,7 +113,7 @@ struct PnvICPState {
|
|||
struct ICSStateClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
void (*realize)(DeviceState *dev, Error **errp);
|
||||
void (*realize)(ICSState *s, Error **errp);
|
||||
void (*pre_save)(ICSState *s);
|
||||
int (*post_load)(ICSState *s, int version_id);
|
||||
void (*reject)(ICSState *s, uint32_t irq);
|
||||
|
@ -129,6 +132,8 @@ struct ICSState {
|
|||
XICSFabric *xics;
|
||||
};
|
||||
|
||||
#define ICS_PROP_XICS "xics"
|
||||
|
||||
static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
|
||||
{
|
||||
return (ics->offset != 0) && (nr >= ics->offset)
|
||||
|
@ -182,8 +187,6 @@ void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle);
|
|||
|
||||
qemu_irq xics_get_qirq(XICSFabric *xi, int irq);
|
||||
ICPState *xics_icp_get(XICSFabric *xi, int server);
|
||||
void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp);
|
||||
void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu);
|
||||
|
||||
/* Internal XICS interfaces */
|
||||
void icp_set_cppr(ICPState *icp, uint8_t cppr);
|
||||
|
|
|
@ -478,7 +478,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
|
|||
}
|
||||
}
|
||||
|
||||
bool kvmppc_is_mem_backend_page_size_ok(char *obj_path)
|
||||
bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path)
|
||||
{
|
||||
Object *mem_obj = object_resolve_path(obj_path, NULL);
|
||||
char *mempath = object_property_get_str(mem_obj, "mem-path", NULL);
|
||||
|
@ -486,6 +486,7 @@ bool kvmppc_is_mem_backend_page_size_ok(char *obj_path)
|
|||
|
||||
if (mempath) {
|
||||
pagesize = qemu_mempath_getpagesize(mempath);
|
||||
g_free(mempath);
|
||||
} else {
|
||||
pagesize = getpagesize();
|
||||
}
|
||||
|
@ -499,7 +500,7 @@ static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu)
|
|||
{
|
||||
}
|
||||
|
||||
bool kvmppc_is_mem_backend_page_size_ok(char *obj_path)
|
||||
bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ int kvmppc_enable_hwrng(void);
|
|||
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
|
||||
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
|
||||
|
||||
bool kvmppc_is_mem_backend_page_size_ok(char *obj_path);
|
||||
bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -211,7 +211,7 @@ static inline uint64_t kvmppc_rma_size(uint64_t current_size,
|
|||
return ram_size;
|
||||
}
|
||||
|
||||
static inline bool kvmppc_is_mem_backend_page_size_ok(char *obj_path)
|
||||
static inline bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue