aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc')
-rw-r--r--hw/ppc/mac_newworld.c15
-rw-r--r--hw/ppc/pnv.c6
-rw-r--r--hw/ppc/ppc405_uc.c6
-rw-r--r--hw/ppc/ppc4xx_pci.c13
-rw-r--r--hw/ppc/spapr.c255
-rw-r--r--hw/ppc/spapr_cpu_core.c137
-rw-r--r--hw/ppc/spapr_ovec.c19
-rw-r--r--hw/ppc/trace-events12
8 files changed, 246 insertions, 217 deletions
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 716aea6852..68aaedc06d 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -72,6 +72,7 @@
#include "exec/address-spaces.h"
#include "hw/sysbus.h"
#include "qemu/cutils.h"
+#include "trace.h"
#define MAX_IDE_BUS 2
#define CFG_ADDR 0xf0000510
@@ -79,21 +80,11 @@
#define CLOCKFREQ (266UL * 1000UL * 1000UL)
#define BUSFREQ (100UL * 1000UL * 1000UL)
-/* debug UniNorth */
-//#define DEBUG_UNIN
-
-#ifdef DEBUG_UNIN
-#define UNIN_DPRINTF(fmt, ...) \
- do { printf("UNIN: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define UNIN_DPRINTF(fmt, ...)
-#endif
-
/* UniN device */
static void unin_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
- UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
+ trace_mac99_uninorth_write(addr, value);
if (addr == 0x0) {
*(int*)opaque = value;
}
@@ -109,7 +100,7 @@ static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
value = *(int*)opaque;
}
- UNIN_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", addr, value);
+ trace_mac99_uninorth_read(addr, value);
return value;
}
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 4fab5c0ae7..09f0d22def 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -381,7 +381,7 @@ static void ppc_powernv_init(MachineState *machine)
fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);
if (fw_size < 0) {
- error_report("qemu: could not load OPAL '%s'", fw_filename);
+ error_report("Could not load OPAL '%s'", fw_filename);
exit(1);
}
g_free(fw_filename);
@@ -393,7 +393,7 @@ static void ppc_powernv_init(MachineState *machine)
kernel_size = load_image_targphys(machine->kernel_filename,
KERNEL_LOAD_ADDR, 0x2000000);
if (kernel_size < 0) {
- error_report("qemu: could not load kernel'%s'",
+ error_report("Could not load kernel '%s'",
machine->kernel_filename);
exit(1);
}
@@ -405,7 +405,7 @@ static void ppc_powernv_init(MachineState *machine)
pnv->initrd_size = load_image_targphys(machine->initrd_filename,
pnv->initrd_base, 0x10000000); /* 128MB max */
if (pnv->initrd_size < 0) {
- error_report("qemu: could not load initial ram disk '%s'",
+ error_report("Could not load initial ram disk '%s'",
machine->initrd_filename);
exit(1);
}
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index d6d3fc2c4a..d5df94aa6e 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1881,7 +1881,7 @@ static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */
D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */
M = D0 * D1 * D2;
- VCO_out = cpc->sysclk * M;
+ VCO_out = (uint64_t)cpc->sysclk * M;
if (VCO_out < 400000000 || VCO_out > 800000000) {
/* PLL cannot lock */
cpc->pllmr &= ~0x80000000;
@@ -1892,7 +1892,7 @@ static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
/* Bypass PLL */
bypass_pll:
M = D0;
- PLL_out = cpc->sysclk * M;
+ PLL_out = (uint64_t)cpc->sysclk * M;
}
CPU_clk = PLL_out;
if (cpc->cr1 & 0x00800000)
@@ -2242,7 +2242,7 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
#ifdef DEBUG_CLOCKS_LL
printf("FWDA %01" PRIx32 " %d\n", (cpc->pllmr[1] >> 16) & 0x7, D);
#endif
- VCO_out = cpc->sysclk * M * D;
+ VCO_out = (uint64_t)cpc->sysclk * M * D;
if (VCO_out < 500000000UL || VCO_out > 1000000000UL) {
/* Error - unlock the PLL */
printf("VCO out of range %" PRIu64 "\n", VCO_out);
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 683218e5c5..dc19682970 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -26,13 +26,7 @@
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "exec/address-spaces.h"
-
-#undef DEBUG
-#ifdef DEBUG
-#define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif /* DEBUG */
+#include "trace.h"
struct PCIMasterMap {
uint32_t la;
@@ -249,8 +243,7 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
{
int slot = pci_dev->devfn >> 3;
- DPRINTF("%s: devfn %x irq %d -> %d\n", __func__,
- pci_dev->devfn, irq_num, slot);
+ trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot);
return slot - 1;
}
@@ -259,7 +252,7 @@ static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
{
qemu_irq *pci_irqs = opaque;
- DPRINTF("%s: PCI irq %d\n", __func__, irq_num);
+ trace_ppc4xx_pci_set_irq(irq_num);
if (irq_num < 0) {
fprintf(stderr, "%s: PCI irq %d\n", __func__, irq_num);
return;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index e465d7ac98..5904e6498f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -958,7 +958,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
_FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
}
- if (mc->query_hotpluggable_cpus) {
+ if (mc->has_hotpluggable_cpus) {
int offset = fdt_path_offset(fdt, "/cpus");
ret = spapr_drc_populate_dt(fdt, offset, NULL,
SPAPR_DR_CONNECTOR_TYPE_CPU);
@@ -1751,13 +1751,28 @@ static void spapr_validate_node_memory(MachineState *machine, Error **errp)
}
}
+/* find cpu slot in machine->possible_cpus by core_id */
+static CPUArchId *spapr_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)
+{
+ int index = id / smp_threads;
+
+ if (index >= ms->possible_cpus->len) {
+ return NULL;
+ }
+ if (idx) {
+ *idx = index;
+ }
+ return &ms->possible_cpus->cpus[index];
+}
+
static void spapr_init_cpus(sPAPRMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(machine);
char *type = spapr_get_cpu_core_type(machine->cpu_model);
int smt = kvmppc_smt_threads();
- int spapr_max_cores, spapr_cores;
+ const CPUArchIdList *possible_cpus;
+ int boot_cores_nr = smp_cpus / smp_threads;
int i;
if (!type) {
@@ -1765,7 +1780,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
exit(1);
}
- if (mc->query_hotpluggable_cpus) {
+ possible_cpus = mc->possible_cpu_arch_ids(machine);
+ if (mc->has_hotpluggable_cpus) {
if (smp_cpus % smp_threads) {
error_report("smp_cpus (%u) must be multiple of threads (%u)",
smp_cpus, smp_threads);
@@ -1776,24 +1792,18 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
max_cpus, smp_threads);
exit(1);
}
-
- spapr_max_cores = max_cpus / smp_threads;
- spapr_cores = smp_cpus / smp_threads;
} else {
if (max_cpus != smp_cpus) {
error_report("This machine version does not support CPU hotplug");
exit(1);
}
-
- spapr_max_cores = QEMU_ALIGN_UP(smp_cpus, smp_threads) / smp_threads;
- spapr_cores = spapr_max_cores;
+ boot_cores_nr = possible_cpus->len;
}
- spapr->cores = g_new0(Object *, spapr_max_cores);
- for (i = 0; i < spapr_max_cores; i++) {
+ for (i = 0; i < possible_cpus->len; i++) {
int core_id = i * smp_threads;
- if (mc->query_hotpluggable_cpus) {
+ if (mc->has_hotpluggable_cpus) {
sPAPRDRConnector *drc =
spapr_dr_connector_new(OBJECT(spapr),
SPAPR_DR_CONNECTOR_TYPE_CPU,
@@ -1802,7 +1812,7 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
qemu_register_reset(spapr_drc_reset, drc);
}
- if (i < spapr_cores) {
+ if (i < boot_cores_nr) {
Object *core = object_new(type);
int nr_threads = smp_threads;
@@ -2357,6 +2367,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
uint64_t align = memory_region_get_alignment(mr);
uint64_t size = memory_region_size(mr);
uint64_t addr;
+ char *mem_dev;
if (size % SPAPR_MEMORY_BLOCK_SIZE) {
error_setg(&local_err, "Hotplugged memory size must be a multiple of "
@@ -2364,6 +2375,13 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
goto out;
}
+ mem_dev = object_property_get_str(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, NULL);
+ if (mem_dev && !kvmppc_is_mem_backend_page_size_ok(mem_dev)) {
+ error_setg(&local_err, "Memory backend has bad page size. "
+ "Use 'memory-backend-file' with correct mem-path.");
+ goto out;
+ }
+
pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err);
if (local_err) {
goto out;
@@ -2488,6 +2506,165 @@ void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
return fdt;
}
+static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ CPUCore *cc = CPU_CORE(dev);
+ CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL);
+
+ core_slot->cpu = NULL;
+ object_unparent(OBJECT(dev));
+}
+
+static void spapr_core_release(DeviceState *dev, void *opaque)
+{
+ HotplugHandler *hotplug_ctrl;
+
+ hotplug_ctrl = qdev_get_hotplug_handler(dev);
+ hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
+}
+
+static
+void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ int index;
+ sPAPRDRConnector *drc;
+ sPAPRDRConnectorClass *drck;
+ Error *local_err = NULL;
+ CPUCore *cc = CPU_CORE(dev);
+ int smt = kvmppc_smt_threads();
+
+ if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {
+ error_setg(errp, "Unable to find CPU core with core-id: %d",
+ cc->core_id);
+ return;
+ }
+ if (index == 0) {
+ error_setg(errp, "Boot CPU core may not be unplugged");
+ return;
+ }
+
+ drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
+ g_assert(drc);
+
+ drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ drck->detach(drc, dev, spapr_core_release, NULL, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ spapr_hotplug_req_remove_by_index(drc);
+}
+
+static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
+ MachineClass *mc = MACHINE_GET_CLASS(spapr);
+ sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
+ CPUCore *cc = CPU_CORE(dev);
+ CPUState *cs = CPU(core->threads);
+ sPAPRDRConnector *drc;
+ Error *local_err = NULL;
+ void *fdt = NULL;
+ int fdt_offset = 0;
+ int smt = kvmppc_smt_threads();
+ CPUArchId *core_slot;
+ int index;
+
+ core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
+ if (!core_slot) {
+ error_setg(errp, "Unable to find CPU core with core-id: %d",
+ cc->core_id);
+ return;
+ }
+ drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
+
+ g_assert(drc || !mc->has_hotpluggable_cpus);
+
+ /*
+ * Setup CPU DT entries only for hotplugged CPUs. For boot time or
+ * coldplugged CPUs DT entries are setup in spapr_build_fdt().
+ */
+ if (dev->hotplugged) {
+ fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr);
+ }
+
+ if (drc) {
+ sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, &local_err);
+ if (local_err) {
+ g_free(fdt);
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ if (dev->hotplugged) {
+ /*
+ * Send hotplug notification interrupt to the guest only in case
+ * of hotplugged CPUs.
+ */
+ spapr_hotplug_req_add_by_index(drc);
+ } else {
+ /*
+ * Set the right DRC states for cold plugged CPU.
+ */
+ if (drc) {
+ sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE);
+ drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED);
+ }
+ }
+ core_slot->cpu = OBJECT(dev);
+}
+
+static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
+{
+ MachineState *machine = MACHINE(OBJECT(hotplug_dev));
+ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
+ Error *local_err = NULL;
+ CPUCore *cc = CPU_CORE(dev);
+ char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
+ const char *type = object_get_typename(OBJECT(dev));
+ CPUArchId *core_slot;
+ int index;
+
+ if (dev->hotplugged && !mc->has_hotpluggable_cpus) {
+ error_setg(&local_err, "CPU hotplug not supported for this machine");
+ goto out;
+ }
+
+ if (strcmp(base_core_type, type)) {
+ error_setg(&local_err, "CPU core type should be %s", base_core_type);
+ goto out;
+ }
+
+ if (cc->core_id % smp_threads) {
+ error_setg(&local_err, "invalid core id %d", cc->core_id);
+ goto out;
+ }
+
+ core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
+ if (!core_slot) {
+ error_setg(&local_err, "core id %d out of range", cc->core_id);
+ goto out;
+ }
+
+ if (core_slot->cpu) {
+ error_setg(&local_err, "core %d already populated", cc->core_id);
+ goto out;
+ }
+
+out:
+ g_free(base_core_type);
+ error_propagate(errp, local_err);
+}
+
static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -2550,7 +2727,7 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev,
error_setg(errp, "Memory hot unplug not supported for this guest");
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
- if (!mc->query_hotpluggable_cpus) {
+ if (!mc->has_hotpluggable_cpus) {
error_setg(errp, "CPU hot unplug not supported on this machine");
return;
}
@@ -2577,11 +2754,11 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
error_setg(errp, "Memory hot unplug not supported for this guest");
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
- if (!mc->query_hotpluggable_cpus) {
+ if (!mc->has_hotpluggable_cpus) {
error_setg(errp, "CPU hot unplug not supported on this machine");
return;
}
- spapr_core_unplug(hotplug_dev, dev, errp);
+ spapr_core_unplug_request(hotplug_dev, dev, errp);
}
}
@@ -2610,35 +2787,34 @@ static unsigned spapr_cpu_index_to_socket_id(unsigned cpu_index)
return cpu_index / smp_threads / smp_cores;
}
-static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine)
+static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
{
int i;
- HotpluggableCPUList *head = NULL;
- sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
int spapr_max_cores = max_cpus / smp_threads;
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
- for (i = 0; i < spapr_max_cores; i++) {
- HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
- HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
- CpuInstanceProperties *cpu_props = g_new0(typeof(*cpu_props), 1);
+ if (!mc->has_hotpluggable_cpus) {
+ spapr_max_cores = QEMU_ALIGN_UP(smp_cpus, smp_threads) / smp_threads;
+ }
+ if (machine->possible_cpus) {
+ assert(machine->possible_cpus->len == spapr_max_cores);
+ return machine->possible_cpus;
+ }
+
+ machine->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
+ sizeof(CPUArchId) * spapr_max_cores);
+ machine->possible_cpus->len = spapr_max_cores;
+ for (i = 0; i < machine->possible_cpus->len; i++) {
+ int core_id = i * smp_threads;
- cpu_item->type = spapr_get_cpu_core_type(machine->cpu_model);
- cpu_item->vcpus_count = smp_threads;
- cpu_props->has_core_id = true;
- cpu_props->core_id = i * smp_threads;
+ machine->possible_cpus->cpus[i].vcpus_count = smp_threads;
+ machine->possible_cpus->cpus[i].arch_id = core_id;
+ machine->possible_cpus->cpus[i].props.has_core_id = true;
+ machine->possible_cpus->cpus[i].props.core_id = core_id;
/* TODO: add 'has_node/node' here to describe
to which node core belongs */
-
- cpu_item->props = cpu_props;
- if (spapr->cores[i]) {
- cpu_item->has_qom_path = true;
- cpu_item->qom_path = object_get_canonical_path(spapr->cores[i]);
- }
- list_item->value = cpu_item;
- list_item->next = head;
- head = list_item;
}
- return head;
+ return machine->possible_cpus;
}
static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
@@ -2724,11 +2900,12 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->plug = spapr_machine_device_plug;
hc->unplug = spapr_machine_device_unplug;
mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id;
+ mc->possible_cpu_arch_ids = spapr_possible_cpu_arch_ids;
hc->unplug_request = spapr_machine_device_unplug_request;
smc->dr_lmb_enabled = true;
smc->tcg_default_cpu = "POWER8";
- mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus;
+ mc->has_hotpluggable_cpus = true;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
smc->phb_placement = spapr_phb_placement;
@@ -2928,7 +3105,7 @@ static void spapr_machine_2_6_instance_options(MachineState *machine)
static void spapr_machine_2_6_class_options(MachineClass *mc)
{
spapr_machine_2_7_class_options(mc);
- mc->query_hotpluggable_cpus = NULL;
+ mc->has_hotpluggable_cpus = false;
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6);
}
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 9dddaeb3fa..55cd0456eb 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -109,13 +109,12 @@ char *spapr_get_cpu_core_type(const char *model)
return core_type;
}
-static void spapr_core_release(DeviceState *dev, void *opaque)
+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));
const char *typename = object_class_get_name(scc->cpu_class);
size_t size = object_type_get_instance_size(typename);
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
CPUCore *cc = CPU_CORE(dev);
int i;
@@ -129,140 +128,7 @@ static void spapr_core_release(DeviceState *dev, void *opaque)
cpu_remove_sync(cs);
object_unparent(obj);
}
-
- spapr->cores[cc->core_id / smp_threads] = NULL;
-
g_free(sc->threads);
- object_unparent(OBJECT(dev));
-}
-
-void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
-{
- CPUCore *cc = CPU_CORE(dev);
- int smt = kvmppc_smt_threads();
- int index = cc->core_id / smp_threads;
- sPAPRDRConnector *drc =
- spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
- sPAPRDRConnectorClass *drck;
- Error *local_err = NULL;
-
- if (index == 0) {
- error_setg(errp, "Boot CPU core may not be unplugged");
- return;
- }
-
- g_assert(drc);
-
- drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
- drck->detach(drc, dev, spapr_core_release, NULL, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- spapr_hotplug_req_remove_by_index(drc);
-}
-
-void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
-{
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- MachineClass *mc = MACHINE_GET_CLASS(spapr);
- sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));
- CPUCore *cc = CPU_CORE(dev);
- CPUState *cs = CPU(core->threads);
- sPAPRDRConnector *drc;
- Error *local_err = NULL;
- void *fdt = NULL;
- int fdt_offset = 0;
- int index = cc->core_id / smp_threads;
- int smt = kvmppc_smt_threads();
-
- drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);
- spapr->cores[index] = OBJECT(dev);
-
- g_assert(drc || !mc->query_hotpluggable_cpus);
-
- /*
- * Setup CPU DT entries only for hotplugged CPUs. For boot time or
- * coldplugged CPUs DT entries are setup in spapr_build_fdt().
- */
- if (dev->hotplugged) {
- fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr);
- }
-
- if (drc) {
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
- drck->attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, &local_err);
- if (local_err) {
- g_free(fdt);
- spapr->cores[index] = NULL;
- error_propagate(errp, local_err);
- return;
- }
- }
-
- if (dev->hotplugged) {
- /*
- * Send hotplug notification interrupt to the guest only in case
- * of hotplugged CPUs.
- */
- spapr_hotplug_req_add_by_index(drc);
- } else {
- /*
- * Set the right DRC states for cold plugged CPU.
- */
- if (drc) {
- sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
- drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE);
- drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED);
- }
- }
-}
-
-void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
-{
- MachineState *machine = MACHINE(OBJECT(hotplug_dev));
- MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
- sPAPRMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev));
- int spapr_max_cores = max_cpus / smp_threads;
- int index;
- Error *local_err = NULL;
- CPUCore *cc = CPU_CORE(dev);
- char *base_core_type = spapr_get_cpu_core_type(machine->cpu_model);
- const char *type = object_get_typename(OBJECT(dev));
-
- if (dev->hotplugged && !mc->query_hotpluggable_cpus) {
- error_setg(&local_err, "CPU hotplug not supported for this machine");
- goto out;
- }
-
- if (strcmp(base_core_type, type)) {
- error_setg(&local_err, "CPU core type should be %s", base_core_type);
- goto out;
- }
-
- if (cc->core_id % smp_threads) {
- error_setg(&local_err, "invalid core id %d", cc->core_id);
- goto out;
- }
-
- index = cc->core_id / smp_threads;
- if (index < 0 || index >= spapr_max_cores) {
- error_setg(&local_err, "core id %d out of range", cc->core_id);
- goto out;
- }
-
- if (spapr->cores[index]) {
- error_setg(&local_err, "core %d already populated", cc->core_id);
- goto out;
- }
-
-out:
- g_free(base_core_type);
- error_propagate(errp, local_err);
}
static void spapr_cpu_core_realize_child(Object *child, Error **errp)
@@ -368,6 +234,7 @@ void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
dc->realize = spapr_cpu_core_realize;
+ dc->unrealize = spapr_cpu_core_unrealizefn;
scc->cpu_class = cpu_class_by_name(TYPE_POWERPC_CPU, data);
g_assert(scc->cpu_class);
}
diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c
index 3eb1d5976f..41df4c35ba 100644
--- a/hw/ppc/spapr_ovec.c
+++ b/hw/ppc/spapr_ovec.c
@@ -16,18 +16,9 @@
#include "qemu/bitmap.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
+#include "trace.h"
#include <libfdt.h>
-/* #define DEBUG_SPAPR_OVEC */
-
-#ifdef DEBUG_SPAPR_OVEC
-#define DPRINTFN(fmt, ...) \
- do { fprintf(stderr, fmt "\n", ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTFN(fmt, ...) \
- do { } while (0)
-#endif
-
#define OV_MAXBYTES 256 /* not including length byte */
#define OV_MAXBITS (OV_MAXBYTES * BITS_PER_BYTE)
@@ -210,8 +201,7 @@ sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
for (i = 0; i < vector_len; i++) {
uint8_t entry = ldub_phys(&address_space_memory, addr + i);
if (entry) {
- DPRINTFN("read guest vector %2d, byte %3d / %3d: 0x%.2x",
- vector, i + 1, vector_len, entry);
+ trace_spapr_ovec_parse_vector(vector, i + 1, vector_len, entry);
guest_byte_to_bitmap(entry, ov->bitmap, i * BITS_PER_BYTE);
}
}
@@ -245,10 +235,9 @@ int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
for (i = 1; i < vec_len + 1; i++) {
vec[i] = guest_byte_from_bitmap(ov->bitmap, (i - 1) * BITS_PER_BYTE);
if (vec[i]) {
- DPRINTFN("encoding guest vector byte %3d / %3d: 0x%.2x",
- i, vec_len, vec[i]);
+ trace_spapr_ovec_populate_dt(i, vec_len, vec[i]);
}
}
- return fdt_setprop(fdt, fdt_offset, name, vec, vec_len);
+ return fdt_setprop(fdt, fdt_offset, name, vec, vec_len + 1);
}
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index f46995cdb2..43d265f351 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -56,6 +56,10 @@ spapr_drc_realize_child(uint32_t index, char *childname) "drc: 0x%"PRIx32", chil
spapr_drc_realize_complete(uint32_t index) "drc: 0x%"PRIx32
spapr_drc_unrealize(uint32_t index) "drc: 0x%"PRIx32
+# hw/ppc/spapr_ovec.c
+spapr_ovec_parse_vector(int vector, int byte, uint16_t vec_len, uint8_t entry) "read guest vector %2d, byte %3d / %3d: 0x%.2x"
+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
@@ -85,3 +89,11 @@ rs6000mc_presence_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
rs6000mc_size_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
rs6000mc_size_write(uint32_t addr, uint32_t val) "write addr=%x val=%x"
rs6000mc_parity_read(uint32_t addr, uint32_t val) "read addr=%x val=%x"
+
+# hw/ppc/mac_newworld.c
+mac99_uninorth_write(uint64_t addr, uint64_t value) "addr=0x%" PRIx64 " val=0x%"PRIx64
+mac99_uninorth_read(uint64_t addr, uint64_t value) "addr=0x%" PRIx64 " val=0x%"PRIx64
+
+# hw/ppc/ppc4xx_pci.c
+ppc4xx_pci_map_irq(int32_t devfn, int irq_num, int slot) "devfn %x irq %d -> %d"
+ppc4xx_pci_set_irq(int irq_num) "PCI irq %d"