aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-03-20 11:45:37 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-03-20 11:45:38 +0000
commit3a87f8b6859e6221b827ab4737779dddb37553ec (patch)
treeac77d44aba200522bb9311a50849ae12be7387bc
parent06c1bee85a7def8d0139ee6829728a891efe623f (diff)
parent71461b0fef53467d2a85dbd72304dba0e01d8370 (diff)
Merge remote-tracking branch 'remotes/afaerber/tags/ppc-for-2.0' into staging
PowerPC queue for 2.0 * sPAPR loop fix * SPR reset fix * Reduce allocation size of indirect opcode tables * Restrict number of CPU threads * sPAPR H_SET_MODE fixes * sPAPR firmware path fixes * Static and constness cleanups # gpg: Signature made Thu 20 Mar 2014 01:46:14 GMT using RSA key ID 3E7E013F # gpg: Good signature from "Andreas Färber <afaerber@suse.de>" # gpg: aka "Andreas Färber <afaerber@suse.com>" * remotes/afaerber/tags/ppc-for-2.0: spapr: Implement interface to fix device pathname spapr: QOM'ify pseries machine spapr_vio: Fix firmware names spapr_llan: Add to boot device list qdev: Introduce FWPathProvider interface vl.c: Extend get_boot_devices_list() to ignore suffixes spapr_hcall: Fix little-endian resource handling in H_SET_MODE target-ppc: Introduce powerisa-207-server flag target-ppc: Force CPU threads count to be a power of 2 target-ppc: Fix overallocation of opcode tables target-ppc: Reset SPRs on CPU reset spapr_hcall: Fix h_enter to loop correctly target-ppc: Add missing 'static' and 'const' attributes Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/core/Makefile.objs1
-rw-r--r--hw/core/fw-path-provider.c51
-rw-r--r--hw/core/qdev.c18
-rw-r--r--hw/net/spapr_llan.c3
-rw-r--r--hw/nvram/fw_cfg.c2
-rw-r--r--hw/ppc/spapr.c107
-rw-r--r--hw/ppc/spapr_hcall.c52
-rw-r--r--hw/ppc/spapr_vio.c3
-rw-r--r--include/hw/fw-path-provider.h47
-rw-r--r--include/hw/ppc/spapr.h9
-rw-r--r--include/sysemu/sysemu.h2
-rw-r--r--target-ppc/arch_dump.c6
-rw-r--r--target-ppc/cpu.h3
-rw-r--r--target-ppc/int_helper.c2
-rw-r--r--target-ppc/machine.c4
-rw-r--r--target-ppc/translate_init.c23
-rw-r--r--tests/Makefile1
-rw-r--r--vl.c8
18 files changed, 307 insertions, 35 deletions
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 981593c7e6..5377d052e9 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -1,5 +1,6 @@
# core qdev-related obj files, also used by *-user:
common-obj-y += qdev.o qdev-properties.o
+common-obj-y += fw-path-provider.o
# irq.o needed for qdev GPIO handling:
common-obj-y += irq.o
common-obj-y += hotplug.o
diff --git a/hw/core/fw-path-provider.c b/hw/core/fw-path-provider.c
new file mode 100644
index 0000000000..b11715733d
--- /dev/null
+++ b/hw/core/fw-path-provider.c
@@ -0,0 +1,51 @@
+/*
+ * Firmware patch provider class and helpers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/fw-path-provider.h"
+
+char *fw_path_provider_get_dev_path(FWPathProvider *p, BusState *bus,
+ DeviceState *dev)
+{
+ FWPathProviderClass *k = FW_PATH_PROVIDER_GET_CLASS(p);
+
+ return k->get_dev_path(p, bus, dev);
+}
+
+char *fw_path_provider_try_get_dev_path(Object *o, BusState *bus,
+ DeviceState *dev)
+{
+ FWPathProvider *p = (FWPathProvider *)
+ object_dynamic_cast(o, TYPE_FW_PATH_PROVIDER);
+
+ if (p) {
+ return fw_path_provider_get_dev_path(p, bus, dev);
+ }
+
+ return NULL;
+}
+
+static const TypeInfo fw_path_provider_info = {
+ .name = TYPE_FW_PATH_PROVIDER,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(FWPathProviderClass),
+};
+
+static void fw_path_provider_register_types(void)
+{
+ type_register_static(&fw_path_provider_info);
+}
+
+type_init(fw_path_provider_register_types)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 97acf62906..60f9df1ed9 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -26,6 +26,7 @@
this API directly. */
#include "hw/qdev.h"
+#include "hw/fw-path-provider.h"
#include "sysemu/sysemu.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
@@ -570,6 +571,18 @@ static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
return NULL;
}
+static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
+{
+ Object *obj = OBJECT(dev);
+ char *d = NULL;
+
+ while (!d && obj->parent) {
+ obj = obj->parent;
+ d = fw_path_provider_try_get_dev_path(obj, bus, dev);
+ }
+ return d;
+}
+
static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
{
int l = 0;
@@ -577,7 +590,10 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
if (dev && dev->parent_bus) {
char *d;
l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
- d = bus_get_fw_dev_path(dev->parent_bus, dev);
+ d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
+ if (!d) {
+ d = bus_get_fw_dev_path(dev->parent_bus, dev);
+ }
if (d) {
l += snprintf(p + l, size - l, "%s", d);
g_free(d);
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index f6fbcb56bf..c433337b67 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -29,6 +29,7 @@
#include "hw/qdev.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
+#include "sysemu/sysemu.h"
#include <libfdt.h>
@@ -213,6 +214,8 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
+ add_boot_device_path(dev->nicconf.bootindex, DEVICE(dev), "");
+
return 0;
}
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index cb36dc2d0c..282341ac1b 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -504,7 +504,7 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data)
{
size_t len;
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
- char *bootindex = get_boot_devices_list(&len);
+ char *bootindex = get_boot_devices_list(&len, false);
fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5c9a154d6a..a11e1217b9 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -26,6 +26,7 @@
*/
#include "sysemu/sysemu.h"
#include "hw/hw.h"
+#include "hw/fw-path-provider.h"
#include "elf.h"
#include "net/net.h"
#include "sysemu/blockdev.h"
@@ -45,6 +46,8 @@
#include "hw/pci/msi.h"
#include "hw/pci/pci.h"
+#include "hw/scsi/scsi.h"
+#include "hw/virtio/virtio-scsi.h"
#include "exec/address-spaces.h"
#include "hw/usb.h"
@@ -81,6 +84,8 @@
#define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift))
+#define TYPE_SPAPR_MACHINE "spapr-machine"
+
sPAPREnvironment *spapr;
int spapr_allocate_irq(int hint, bool lsi)
@@ -598,7 +603,9 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
hwaddr rtas_addr,
hwaddr rtas_size)
{
- int ret;
+ int ret, i;
+ size_t cb = 0;
+ char *bootlist;
void *fdt;
sPAPRPHBState *phb;
@@ -640,6 +647,21 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
fprintf(stderr, "Couldn't finalize CPU device tree properties\n");
}
+ bootlist = get_boot_devices_list(&cb, true);
+ if (cb && bootlist) {
+ int offset = fdt_path_offset(fdt, "/chosen");
+ if (offset < 0) {
+ exit(1);
+ }
+ for (i = 0; i < cb; i++) {
+ if (bootlist[i] == '\n') {
+ bootlist[i] = ' ';
+ }
+
+ }
+ ret = fdt_setprop_string(fdt, offset, "qemu,boot-list", bootlist);
+ }
+
if (!spapr->has_graphics) {
spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
}
@@ -1410,9 +1432,86 @@ static QEMUMachine spapr_machine = {
.kvm_type = spapr_kvm_type,
};
-static void spapr_machine_init(void)
+/*
+ * Implementation of an interface to adjust firmware patch
+ * for the bootindex property handling.
+ */
+static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+ DeviceState *dev)
+{
+#define CAST(type, obj, name) \
+ ((type *)object_dynamic_cast(OBJECT(obj), (name)))
+ SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE);
+ sPAPRPHBState *phb = CAST(sPAPRPHBState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
+
+ if (d) {
+ void *spapr = CAST(void, bus->parent, "spapr-vscsi");
+ VirtIOSCSI *virtio = CAST(VirtIOSCSI, bus->parent, TYPE_VIRTIO_SCSI);
+ USBDevice *usb = CAST(USBDevice, bus->parent, TYPE_USB_DEVICE);
+
+ if (spapr) {
+ /*
+ * Replace "channel@0/disk@0,0" with "disk@8000000000000000":
+ * We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun
+ * in the top 16 bits of the 64-bit LUN
+ */
+ unsigned id = 0x8000 | (d->id << 8) | d->lun;
+ return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
+ (uint64_t)id << 48);
+ } else if (virtio) {
+ /*
+ * We use SRP luns of the form 01000000 | (target << 8) | lun
+ * in the top 32 bits of the 64-bit LUN
+ * Note: the quote above is from SLOF and it is wrong,
+ * the actual binding is:
+ * swap 0100 or 10 << or 20 << ( target lun-id -- srplun )
+ */
+ unsigned id = 0x1000000 | (d->id << 16) | d->lun;
+ return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
+ (uint64_t)id << 32);
+ } else if (usb) {
+ /*
+ * We use SRP luns of the form 01000000 | (usb-port << 16) | lun
+ * in the top 32 bits of the 64-bit LUN
+ */
+ unsigned usb_port = atoi(usb->port->path);
+ unsigned id = 0x1000000 | (usb_port << 16) | d->lun;
+ return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev),
+ (uint64_t)id << 32);
+ }
+ }
+
+ if (phb) {
+ /* Replace "pci" with "pci@800000020000000" */
+ return g_strdup_printf("pci@%"PRIX64, phb->buid);
+ }
+
+ return NULL;
+}
+
+static void spapr_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
+
+ mc->qemu_machine = data;
+ fwc->get_dev_path = spapr_get_fw_dev_path;
+}
+
+static const TypeInfo spapr_machine_info = {
+ .name = TYPE_SPAPR_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = spapr_machine_class_init,
+ .class_data = &spapr_machine,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_FW_PATH_PROVIDER },
+ { }
+ },
+};
+
+static void spapr_machine_register_types(void)
{
- qemu_register_machine(&spapr_machine);
+ type_register_static(&spapr_machine_info);
}
-machine_init(spapr_machine_init);
+type_init(spapr_machine_register_types)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index e999bbaea0..0bae0535e8 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -4,6 +4,36 @@
#include "hw/ppc/spapr.h"
#include "mmu-hash64.h"
+struct SPRSyncState {
+ CPUState *cs;
+ int spr;
+ target_ulong value;
+ target_ulong mask;
+};
+
+static void do_spr_sync(void *arg)
+{
+ struct SPRSyncState *s = arg;
+ PowerPCCPU *cpu = POWERPC_CPU(s->cs);
+ CPUPPCState *env = &cpu->env;
+
+ cpu_synchronize_state(s->cs);
+ env->spr[s->spr] &= ~s->mask;
+ env->spr[s->spr] |= s->value;
+}
+
+static void set_spr(CPUState *cs, int spr, target_ulong value,
+ target_ulong mask)
+{
+ struct SPRSyncState s = {
+ .cs = cs,
+ .spr = spr,
+ .value = value,
+ .mask = mask
+ };
+ run_on_cpu(cs, do_spr_sync, &s);
+}
+
static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
target_ulong pte_index)
{
@@ -110,16 +140,15 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
if (likely((flags & H_EXACT) == 0)) {
pte_index &= ~7ULL;
token = ppc_hash64_start_access(cpu, pte_index);
- do {
- if (index == 8) {
- ppc_hash64_stop_access(token);
- return H_PTEG_FULL;
- }
+ for (; index < 8; index++) {
if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
break;
}
- } while (index++);
+ }
ppc_hash64_stop_access(token);
+ if (index == 8) {
+ return H_PTEG_FULL;
+ }
} else {
token = ppc_hash64_start_access(cpu, pte_index);
if (ppc_hash64_load_hpte0(env, token, 0) & HPTE64_V_VALID) {
@@ -690,7 +719,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
target_ulong value2 = args[3];
target_ulong ret = H_P2;
- if (resource == H_SET_MODE_ENDIAN) {
+ if (resource == H_SET_MODE_RESOURCE_LE) {
if (value1) {
ret = H_P3;
goto out;
@@ -699,22 +728,17 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
ret = H_P4;
goto out;
}
-
switch (mflags) {
case H_SET_MODE_ENDIAN_BIG:
CPU_FOREACH(cs) {
- PowerPCCPU *cp = POWERPC_CPU(cs);
- CPUPPCState *env = &cp->env;
- env->spr[SPR_LPCR] &= ~LPCR_ILE;
+ set_spr(cs, SPR_LPCR, 0, LPCR_ILE);
}
ret = H_SUCCESS;
break;
case H_SET_MODE_ENDIAN_LITTLE:
CPU_FOREACH(cs) {
- PowerPCCPU *cp = POWERPC_CPU(cs);
- CPUPPCState *env = &cp->env;
- env->spr[SPR_LPCR] |= LPCR_ILE;
+ set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE);
}
ret = H_SUCCESS;
break;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 4e33f462d9..2ae06a3356 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -68,6 +68,7 @@ static void spapr_vio_bus_class_init(ObjectClass *klass, void *data)
BusClass *k = BUS_CLASS(klass);
k->get_dev_path = spapr_vio_get_dev_name;
+ k->get_fw_dev_path = spapr_vio_get_dev_name;
}
static const TypeInfo spapr_vio_bus_info = {
@@ -529,7 +530,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev)
static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->fw_name = "vdevice";
k->init = spapr_vio_bridge_init;
}
diff --git a/include/hw/fw-path-provider.h b/include/hw/fw-path-provider.h
new file mode 100644
index 0000000000..301834972c
--- /dev/null
+++ b/include/hw/fw-path-provider.h
@@ -0,0 +1,47 @@
+/*
+ * Firmware patch provider class and helpers definitions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FW_PATH_PROVIDER_H
+#define FW_PATH_PROVIDER_H 1
+
+#include "qemu-common.h"
+#include "qom/object.h"
+
+#define TYPE_FW_PATH_PROVIDER "fw-path-provider"
+
+#define FW_PATH_PROVIDER_CLASS(klass) \
+ OBJECT_CLASS_CHECK(FWPathProviderClass, (klass), TYPE_FW_PATH_PROVIDER)
+#define FW_PATH_PROVIDER_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(FWPathProviderClass, (obj), TYPE_FW_PATH_PROVIDER)
+#define FW_PATH_PROVIDER(obj) \
+ INTERFACE_CHECK(FWPathProvider, (obj), TYPE_FW_PATH_PROVIDER)
+
+typedef struct FWPathProvider {
+ Object parent_obj;
+} FWPathProvider;
+
+typedef struct FWPathProviderClass {
+ InterfaceClass parent_class;
+
+ char *(*get_dev_path)(FWPathProvider *p, BusState *bus, DeviceState *dev);
+} FWPathProviderClass;
+
+char *fw_path_provider_get_dev_path(FWPathProvider *p, BusState *bus,
+ DeviceState *dev);
+char *fw_path_provider_try_get_dev_path(Object *o, BusState *bus,
+ DeviceState *dev);
+
+#endif /* FW_PATH_PROVIDER_H */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 449fc7ca2d..5fdac1e009 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -153,8 +153,13 @@ typedef struct sPAPREnvironment {
#define H_PP1 (1ULL<<(63-62))
#define H_PP2 (1ULL<<(63-63))
-/* H_SET_MODE flags */
-#define H_SET_MODE_ENDIAN 4
+/* Values for 2nd argument to H_SET_MODE */
+#define H_SET_MODE_RESOURCE_SET_CIABR 1
+#define H_SET_MODE_RESOURCE_SET_DAWR 2
+#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3
+#define H_SET_MODE_RESOURCE_LE 4
+
+/* Flags for H_SET_MODE_RESOURCE_LE */
#define H_SET_MODE_ENDIAN_BIG 0
#define H_SET_MODE_ENDIAN_LITTLE 1
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index c01304d39a..3915ce3204 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -186,7 +186,7 @@ void rtc_change_mon_event(struct tm *tm);
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
const char *suffix);
-char *get_boot_devices_list(size_t *size);
+char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
DeviceState *get_boot_device(uint32_t position);
diff --git a/target-ppc/arch_dump.c b/target-ppc/arch_dump.c
index 17fd4c6fb1..9dccf1ae1f 100644
--- a/target-ppc/arch_dump.c
+++ b/target-ppc/arch_dump.c
@@ -164,7 +164,7 @@ static void ppc64_write_elf64_speregset(Note *note, PowerPCCPU *cpu)
speregset->spe_fscr = cpu_to_be32(cpu->env.spe_fscr);
}
-struct NoteFuncDescStruct {
+static const struct NoteFuncDescStruct {
int contents_size;
void (*note_contents_func)(Note *note, PowerPCCPU *cpu);
} note_func[] = {
@@ -196,7 +196,7 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
int name_size = 8; /* "CORE" or "QEMU" rounded */
size_t elf_note_size = 0;
int note_head_size;
- NoteFuncDesc *nf;
+ const NoteFuncDesc *nf;
if (class != ELFCLASS64) {
return -1;
@@ -221,7 +221,7 @@ static int ppc64_write_all_elf64_notes(const char *note_name,
Note note;
int ret = -1;
int note_size;
- NoteFuncDesc *nf;
+ const NoteFuncDesc *nf;
for (nf = note_func; nf->note_contents_func; nf++) {
note.hdr.n_namesz = cpu_to_be32(sizeof(note.name));
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 91b7ae5534..2719c08323 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -334,6 +334,7 @@ struct ppc_spr_t {
void (*hea_write)(void *opaque, int spr_num, int gpr_num);
#endif
const char *name;
+ target_ulong default_value;
#ifdef CONFIG_KVM
/* We (ab)use the fact that all the SPRs will have ids for the
* ONE_REG interface will have KVM_REG_PPC to use 0 as meaning,
@@ -1900,6 +1901,8 @@ enum {
PPC2_LSQ_ISA207 = 0x0000000000002000ULL,
/* ISA 2.07 Altivec */
PPC2_ALTIVEC_207 = 0x0000000000004000ULL,
+ /* PowerISA 2.07 Book3s specification */
+ PPC2_ISA207S = 0x0000000000008000ULL,
#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index e14e304457..18b54f060a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1075,7 +1075,7 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
#undef VBPERMQ_INDEX
#undef VBPERMQ_DW
-uint64_t VGBBD_MASKS[256] = {
+static const uint64_t VGBBD_MASKS[256] = {
0x0000000000000000ull, /* 00 */
0x0000000000000080ull, /* 01 */
0x0000000000008000ull, /* 02 */
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 2d46ceccca..063b379d90 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -114,7 +114,7 @@ static void put_avr(QEMUFile *f, void *pv, size_t size)
qemu_put_be64(f, v->u64[1]);
}
-const VMStateInfo vmstate_info_avr = {
+static const VMStateInfo vmstate_info_avr = {
.name = "avr",
.get = get_avr,
.put = put_avr,
@@ -288,7 +288,7 @@ static void put_slbe(QEMUFile *f, void *pv, size_t size)
qemu_put_be64(f, v->vsid);
}
-const VMStateInfo vmstate_info_slbe = {
+static const VMStateInfo vmstate_info_slbe = {
.name = "slbe",
.get = get_slbe,
.put = put_slbe,
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6084f40f28..7f53c33eaf 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -631,7 +631,7 @@ static inline void _spr_register(CPUPPCState *env, int num,
#if defined(CONFIG_KVM)
spr->one_reg_id = one_reg_id,
#endif
- env->spr[num] = initial_value;
+ env->spr[num] = spr->default_value = initial_value;
}
/* Generic PowerPC SPRs */
@@ -7173,7 +7173,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
- PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207;
+ PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
+ PPC2_ISA205 | PPC2_ISA207S;
pcc->msr_mask = 0x800000000284FF36ULL;
pcc->mmu_model = POWERPC_MMU_2_06;
#if defined(CONFIG_SOFTMMU)
@@ -7434,7 +7435,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
{
opc_handler_t **tmp;
- tmp = g_malloc(0x20 * sizeof(opc_handler_t));
+ tmp = g_new(opc_handler_t *, 0x20);
fill_new_table(tmp, 0x20);
table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
@@ -7848,6 +7849,12 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
max_smt, kvm_enabled() ? "KVM" : "TCG");
return;
}
+ if (!is_power_of_2(smp_threads)) {
+ error_setg(errp, "Cannot support %d threads on PPC with %s, "
+ "threads count must be a power of 2.",
+ smp_threads, kvm_enabled() ? "KVM" : "TCG");
+ return;
+ }
cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
+ (cs->cpu_index % smp_threads);
@@ -8381,6 +8388,7 @@ static void ppc_cpu_reset(CPUState *s)
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
CPUPPCState *env = &cpu->env;
target_ulong msr;
+ int i;
pcc->parent_reset(s);
@@ -8434,6 +8442,15 @@ static void ppc_cpu_reset(CPUState *s)
env->dtl_size = 0;
#endif /* TARGET_PPC64 */
+ for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+ ppc_spr_t *spr = &env->spr_cb[i];
+
+ if (!spr->name) {
+ continue;
+ }
+ env->spr[i] = spr->default_value;
+ }
+
/* Flush all TLBs */
tlb_flush(s, 1);
}
diff --git a/tests/Makefile b/tests/Makefile
index 471b4c8785..2d021fb16d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -206,6 +206,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o
tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
hw/core/irq.o \
+ hw/core/fw-path-provider.o \
$(qom-core-obj) \
$(test-qapi-obj-y) \
libqemuutil.a libqemustub.a
diff --git a/vl.c b/vl.c
index e2e2ac799e..02bf8ec47a 100644
--- a/vl.c
+++ b/vl.c
@@ -1209,7 +1209,7 @@ DeviceState *get_boot_device(uint32_t position)
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
-char *get_boot_devices_list(size_t *size)
+char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
{
FWBootEntry *i;
size_t total = 0;
@@ -1224,7 +1224,7 @@ char *get_boot_devices_list(size_t *size)
assert(devpath);
}
- if (i->suffix && devpath) {
+ if (i->suffix && !ignore_suffixes && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
bootpath = g_malloc(bootpathlen);
@@ -1232,9 +1232,11 @@ char *get_boot_devices_list(size_t *size)
g_free(devpath);
} else if (devpath) {
bootpath = devpath;
- } else {
+ } else if (!ignore_suffixes) {
assert(i->suffix);
bootpath = g_strdup(i->suffix);
+ } else {
+ bootpath = g_strdup("");
}
if (total) {