mirror of
https://github.com/qemu/qemu.git
synced 2024-11-29 06:43:37 +08:00
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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJTKkhmAAoJEPou0S0+fgE/mTYQAJWNNiq6ti1udxVOXJ1WAuh1 7DTdiigXY0P/iwigebAVJ78Qs4bLZEJQUv5Xz/uaCwRIyk6uEnLf3J+ZSqpKxN5P Bxj2S+ZS4eaPS1eKSKdVAadFOTqmexrD1g1LarpuvDReeKJVzpdVRAGgQcDcI2Hk 0YVjh2MY5GLWFJJNh6Ir/RI9HNp/TGjzGvvZlT0KS6GG9qJE/xRAmpZKVD1YDcjI nmAA0HgEOT1bGgtdNbK7yst8+nPr9WIbmkbTpvcbo5s+EjVR/iqqeAr4DsxUTjIz EXRpVgKrl+GZSwCo+APnXc+4qNaiuiR/WVdKYwkJBE+jbxUx9o/fuQ3nOz+eUWGz 4sv/MC52MA4IUHaNn6Cm8ghVZzseXB8RfLHd7MX978HDyqCsgPkKXoMyjIhvK9de /AB8h8vTdqlKFclIZFYH/fZE/TuAoaIHBJeQtpT1KKmC7lKWlo6x6MW/Z2jYnc6C nwPyGqM/wjRvaOx+dXewPlc/iz9bWrVNBDhSagdFT15gcRjIVh6Fta839dKn38iT +dA6UG1wCMPdK8+EAcf0xWnsnn/rfuUhz5UjizP6srnB2+oEJtdbW1aPDh/lFxTZ nVU8j/jgA16wTVP8v9dWHrHZjCxlclfH/s51M0eT/ClIiozPxSP2DZbhyzqtdTNs +1jfNaIZCEQnvvBQPBsz =clOM -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
3a87f8b685
@ -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
|
||||
|
51
hw/core/fw-path-provider.c
Normal file
51
hw/core/fw-path-provider.c
Normal file
@ -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)
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
107
hw/ppc/spapr.c
107
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)
|
||||
{
|
||||
qemu_register_machine(&spapr_machine);
|
||||
#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;
|
||||
}
|
||||
|
||||
machine_init(spapr_machine_init);
|
||||
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)
|
||||
{
|
||||
type_register_static(&spapr_machine_info);
|
||||
}
|
||||
|
||||
type_init(spapr_machine_register_types)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
47
include/hw/fw-path-provider.h
Normal file
47
include/hw/fw-path-provider.h
Normal file
@ -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 */
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 | \
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
8
vl.c
8
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user