diff options
Diffstat (limited to 'hw/ppc')
-rw-r--r-- | hw/ppc/mac_newworld.c | 15 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 6 | ||||
-rw-r--r-- | hw/ppc/ppc405_uc.c | 6 | ||||
-rw-r--r-- | hw/ppc/ppc4xx_pci.c | 13 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 255 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 137 | ||||
-rw-r--r-- | hw/ppc/spapr_ovec.c | 19 | ||||
-rw-r--r-- | hw/ppc/trace-events | 12 |
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" |