mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 18:44:58 -06: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
18 changed files with 307 additions and 35 deletions
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue