mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 14:24:02 +08:00
ppc patch queue for 2019-03-10
This pull requests supersedes ppc-for-4.0-20190310. Changes are: * Fixed a bunch of minor style problems * Suppressed warnings about Spectre/Meltdown mitigations with TCG * Added one more patch, a preliminary fix towards the not-quite-ready support for NVLink VFIO passthrough. This is a final pull request before the 4.0 soft freeze. Changes include: * A Great Renaming to use camel case properly in spapr code * Optimization of some vector instructions * Support for POWER9 cpus in the powernv machine * Fixes a regression from the last pull request in handling VSX instructions with mixed operands from the FPR and VMX parts of the register array * Optimization hack to avoid scanning all the (empty) entries on a new IOMMU window * Add FSL I2C controller model for E500 * Support for KVM acceleration of the H_PAGE_INIT hypercall on spapr * Update u-boot image for E500 * Enable Specre/Meltdown mitigations by default on the new machine type * Enable large decrementer support for POWER9 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAlyHansACgkQbDjKyiDZ s5Iyag/9FNqklT6zJt+eRTCJnmPOr+oPnU4bpCYysZsVkVBiF96zEJIQQbS91YtN lqUmHtvRo+u+R1kuNr/9fi6zWq91M5TwW/B8t3Herh0qRS2XpeW31l6pXWec5XPe dz8/zoLaXtN95jArl5NyGcN0we4/46Uu/U3hA5Ss7hIos57LyqtzlrBx4tEpp8H1 pBj62xc9qs/iiFDvotNmj9XIQhOWNxeGz6nBXbVxRdWqAjpqZ7EDk0hY8WCG6WWt 9eGISV1ojuv+Wv3MKqW5F8nTIiO+C2AE9NMjzzgqKV6l6hjzt/7gcygalqHioIpe L/DiCvlcReZljcCXS3ImQZ7R9hYIYW4fHjq+0HftO1q4SmGK+L4YAsHZWgLZuT6P y5yauZV1CY/186zzpPElIfn4MNAvZF7gSBu2Lf72I8OfNU7e+udccwP4LuchvbN/ gUwc76uWqk3789uvQlJTMjSt5RuBgMWxgrOd7Xt7bxiFXEFYZR531O1Fr3Fc5a+S UYDg6EzJG+safHakCt2ycHihHLBF7VC0/AIRsDdEM9La5BIkqAhgyUw/g5B4iq6u yuQPAggu+k/sZtNgk+IlhVp24ltzL5xUQauaZr0CgKZKqe4BvIYFyVfjjWlrG6/E aUnxZoDdZuhL7jpW+DSQvyAS11V6YgWt4mW1lK2CRP3VHJKRQqM= =f+No -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190312' into staging ppc patch queue for 2019-03-10 This pull requests supersedes ppc-for-4.0-20190310. Changes are: * Fixed a bunch of minor style problems * Suppressed warnings about Spectre/Meltdown mitigations with TCG * Added one more patch, a preliminary fix towards the not-quite-ready support for NVLink VFIO passthrough. This is a final pull request before the 4.0 soft freeze. Changes include: * A Great Renaming to use camel case properly in spapr code * Optimization of some vector instructions * Support for POWER9 cpus in the powernv machine * Fixes a regression from the last pull request in handling VSX instructions with mixed operands from the FPR and VMX parts of the register array * Optimization hack to avoid scanning all the (empty) entries on a new IOMMU window * Add FSL I2C controller model for E500 * Support for KVM acceleration of the H_PAGE_INIT hypercall on spapr * Update u-boot image for E500 * Enable Specre/Meltdown mitigations by default on the new machine type * Enable large decrementer support for POWER9 # gpg: Signature made Tue 12 Mar 2019 08:14:51 GMT # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-4.0-20190312: (62 commits) vfio: Make vfio_get_region_info_cap public Suppress test warnings about missing Spectre/Meltdown mitigations with TCG spapr: Use CamelCase properly target/ppc: Optimize x[sv]xsigdp using deposit_i64() target/ppc: Optimize xviexpdp() using deposit_i64() target/ppc: add HV support for POWER9 ppc/pnv: add a "ibm,opal/power-mgt" device tree node on POWER9 ppc/pnv: add more dummy XSCOM addresses ppc/pnv: activate XSCOM tests for POWER9 ppc/pnv: POWER9 XSCOM quad support ppc/pnv: extend XSCOM core support for POWER9 ppc/pnv: add a OCC model for POWER9 ppc/pnv: add a OCC model class ppc/pnv: add SerIRQ routing registers ppc/pnv: add a LPC Controller model for POWER9 ppc/pnv: add a 'dt_isa_nodename' to the chip ppc/pnv: add a LPC Controller class model ppc/pnv: lpc: fix OPB address ranges ppc/pnv: add a PSI bridge model for POWER9 ppc/pnv: add a PSI bridge class model ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bc76b71489
@ -984,6 +984,7 @@ L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/ppc/e500*
|
||||
F: hw/gpio/mpc8xxx.c
|
||||
F: hw/i2c/mpc_i2c.c
|
||||
F: hw/net/fsl_etsec/
|
||||
F: hw/pci-host/ppce500.c
|
||||
F: include/hw/ppc/ppc_e500.h
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Default configuration for ppc-softmmu
|
||||
|
||||
# For embedded PPCs:
|
||||
CONFIG_MPC_I2C=y
|
||||
CONFIG_DS1338=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_PPC405=y
|
||||
CONFIG_PPC440=y
|
||||
|
@ -10,27 +10,27 @@
|
||||
|
||||
#define VTERM_BUFSIZE 16
|
||||
|
||||
typedef struct VIOsPAPRVTYDevice {
|
||||
VIOsPAPRDevice sdev;
|
||||
typedef struct SpaprVioVty {
|
||||
SpaprVioDevice sdev;
|
||||
CharBackend chardev;
|
||||
uint32_t in, out;
|
||||
uint8_t buf[VTERM_BUFSIZE];
|
||||
} VIOsPAPRVTYDevice;
|
||||
} SpaprVioVty;
|
||||
|
||||
#define TYPE_VIO_SPAPR_VTY_DEVICE "spapr-vty"
|
||||
#define VIO_SPAPR_VTY_DEVICE(obj) \
|
||||
OBJECT_CHECK(VIOsPAPRVTYDevice, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)
|
||||
OBJECT_CHECK(SpaprVioVty, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)
|
||||
|
||||
static int vty_can_receive(void *opaque)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
|
||||
SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);
|
||||
|
||||
return VTERM_BUFSIZE - (dev->in - dev->out);
|
||||
}
|
||||
|
||||
static void vty_receive(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
|
||||
SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);
|
||||
int i;
|
||||
|
||||
if ((dev->in == dev->out) && size) {
|
||||
@ -51,9 +51,9 @@ static void vty_receive(void *opaque, const uint8_t *buf, int size)
|
||||
}
|
||||
}
|
||||
|
||||
static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
|
||||
static int vty_getchars(SpaprVioDevice *sdev, uint8_t *buf, int max)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
int n = 0;
|
||||
|
||||
while ((n < max) && (dev->out != dev->in)) {
|
||||
@ -83,18 +83,18 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
|
||||
return n;
|
||||
}
|
||||
|
||||
void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
|
||||
void vty_putchars(SpaprVioDevice *sdev, uint8_t *buf, int len)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(&dev->chardev, buf, len);
|
||||
}
|
||||
|
||||
static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
|
||||
static void spapr_vty_realize(SpaprVioDevice *sdev, Error **errp)
|
||||
{
|
||||
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
|
||||
|
||||
if (!qemu_chr_fe_backend_connected(&dev->chardev)) {
|
||||
error_setg(errp, "chardev property not set");
|
||||
@ -106,14 +106,14 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_put_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong len = args[1];
|
||||
target_ulong char0_7 = args[2];
|
||||
target_ulong char8_15 = args[3];
|
||||
VIOsPAPRDevice *sdev;
|
||||
SpaprVioDevice *sdev;
|
||||
uint8_t buf[16];
|
||||
|
||||
sdev = vty_lookup(spapr, reg);
|
||||
@ -133,14 +133,14 @@ static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_get_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong *len = args + 0;
|
||||
target_ulong *char0_7 = args + 1;
|
||||
target_ulong *char8_15 = args + 2;
|
||||
VIOsPAPRDevice *sdev;
|
||||
SpaprVioDevice *sdev;
|
||||
uint8_t buf[16];
|
||||
|
||||
sdev = vty_lookup(spapr, reg);
|
||||
@ -159,7 +159,7 @@ static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev)
|
||||
void spapr_vty_create(SpaprVioBus *bus, Chardev *chardev)
|
||||
{
|
||||
DeviceState *dev;
|
||||
|
||||
@ -169,8 +169,8 @@ void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev)
|
||||
}
|
||||
|
||||
static Property spapr_vty_properties[] = {
|
||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev),
|
||||
DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
|
||||
DEFINE_SPAPR_PROPERTIES(SpaprVioVty, sdev),
|
||||
DEFINE_PROP_CHR("chardev", SpaprVioVty, chardev),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@ -179,11 +179,11 @@ static const VMStateDescription vmstate_spapr_vty = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice),
|
||||
VMSTATE_SPAPR_VIO(sdev, SpaprVioVty),
|
||||
|
||||
VMSTATE_UINT32(in, VIOsPAPRVTYDevice),
|
||||
VMSTATE_UINT32(out, VIOsPAPRVTYDevice),
|
||||
VMSTATE_BUFFER(buf, VIOsPAPRVTYDevice),
|
||||
VMSTATE_UINT32(in, SpaprVioVty),
|
||||
VMSTATE_UINT32(out, SpaprVioVty),
|
||||
VMSTATE_BUFFER(buf, SpaprVioVty),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
@ -191,7 +191,7 @@ static const VMStateDescription vmstate_spapr_vty = {
|
||||
static void spapr_vty_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = spapr_vty_realize;
|
||||
k->dt_name = "vty";
|
||||
@ -205,13 +205,13 @@ static void spapr_vty_class_init(ObjectClass *klass, void *data)
|
||||
static const TypeInfo spapr_vty_info = {
|
||||
.name = TYPE_VIO_SPAPR_VTY_DEVICE,
|
||||
.parent = TYPE_VIO_SPAPR_DEVICE,
|
||||
.instance_size = sizeof(VIOsPAPRVTYDevice),
|
||||
.instance_size = sizeof(SpaprVioVty),
|
||||
.class_init = spapr_vty_class_init,
|
||||
};
|
||||
|
||||
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
|
||||
SpaprVioDevice *spapr_vty_get_default(SpaprVioBus *bus)
|
||||
{
|
||||
VIOsPAPRDevice *sdev, *selected;
|
||||
SpaprVioDevice *sdev, *selected;
|
||||
BusChild *kid;
|
||||
|
||||
/*
|
||||
@ -246,9 +246,9 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
|
||||
return selected;
|
||||
}
|
||||
|
||||
VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg)
|
||||
SpaprVioDevice *vty_lookup(SpaprMachineState *spapr, target_ulong reg)
|
||||
{
|
||||
VIOsPAPRDevice *sdev;
|
||||
SpaprVioDevice *sdev;
|
||||
|
||||
sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
if (!sdev && reg == 0) {
|
||||
|
@ -25,3 +25,7 @@ config BITBANG_I2C
|
||||
config IMX_I2C
|
||||
bool
|
||||
select I2C
|
||||
|
||||
config MPC_I2C
|
||||
bool
|
||||
select I2C
|
||||
|
@ -9,5 +9,6 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
|
||||
common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
|
||||
common-obj-$(CONFIG_ASPEED_SOC) += aspeed_i2c.o
|
||||
common-obj-$(CONFIG_NRF51_SOC) += microbit_i2c.o
|
||||
common-obj-$(CONFIG_MPC_I2C) += mpc_i2c.o
|
||||
obj-$(CONFIG_OMAP) += omap_i2c.o
|
||||
obj-$(CONFIG_PPC4XX) += ppc4xx_i2c.o
|
||||
|
357
hw/i2c/mpc_i2c.c
Normal file
357
hw/i2c/mpc_i2c.c
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Amit Tomar, <Amit.Tomar@freescale.com>
|
||||
*
|
||||
* Description:
|
||||
* This file is derived from IMX I2C controller,
|
||||
* by Jean-Christophe DUBOIS .
|
||||
*
|
||||
* Thanks to Scott Wood and Alexander Graf for their kind help on this.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2 or later,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
#include "qemu/log.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
/* #define DEBUG_I2C */
|
||||
|
||||
#ifdef DEBUG_I2C
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { fprintf(stderr, "mpc_i2c[%s]: " fmt, __func__, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define TYPE_MPC_I2C "mpc-i2c"
|
||||
#define MPC_I2C(obj) \
|
||||
OBJECT_CHECK(MPCI2CState, (obj), TYPE_MPC_I2C)
|
||||
|
||||
#define MPC_I2C_ADR 0x00
|
||||
#define MPC_I2C_FDR 0x04
|
||||
#define MPC_I2C_CR 0x08
|
||||
#define MPC_I2C_SR 0x0c
|
||||
#define MPC_I2C_DR 0x10
|
||||
#define MPC_I2C_DFSRR 0x14
|
||||
|
||||
#define CCR_MEN (1 << 7)
|
||||
#define CCR_MIEN (1 << 6)
|
||||
#define CCR_MSTA (1 << 5)
|
||||
#define CCR_MTX (1 << 4)
|
||||
#define CCR_TXAK (1 << 3)
|
||||
#define CCR_RSTA (1 << 2)
|
||||
#define CCR_BCST (1 << 0)
|
||||
|
||||
#define CSR_MCF (1 << 7)
|
||||
#define CSR_MAAS (1 << 6)
|
||||
#define CSR_MBB (1 << 5)
|
||||
#define CSR_MAL (1 << 4)
|
||||
#define CSR_SRW (1 << 2)
|
||||
#define CSR_MIF (1 << 1)
|
||||
#define CSR_RXAK (1 << 0)
|
||||
|
||||
#define CADR_MASK 0xFE
|
||||
#define CFDR_MASK 0x3F
|
||||
#define CCR_MASK 0xFC
|
||||
#define CSR_MASK 0xED
|
||||
#define CDR_MASK 0xFF
|
||||
|
||||
#define CYCLE_RESET 0xFF
|
||||
|
||||
typedef struct MPCI2CState {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
I2CBus *bus;
|
||||
qemu_irq irq;
|
||||
MemoryRegion iomem;
|
||||
|
||||
uint8_t address;
|
||||
uint8_t adr;
|
||||
uint8_t fdr;
|
||||
uint8_t cr;
|
||||
uint8_t sr;
|
||||
uint8_t dr;
|
||||
uint8_t dfssr;
|
||||
} MPCI2CState;
|
||||
|
||||
static bool mpc_i2c_is_enabled(MPCI2CState *s)
|
||||
{
|
||||
return s->cr & CCR_MEN;
|
||||
}
|
||||
|
||||
static bool mpc_i2c_is_master(MPCI2CState *s)
|
||||
{
|
||||
return s->cr & CCR_MSTA;
|
||||
}
|
||||
|
||||
static bool mpc_i2c_direction_is_tx(MPCI2CState *s)
|
||||
{
|
||||
return s->cr & CCR_MTX;
|
||||
}
|
||||
|
||||
static bool mpc_i2c_irq_pending(MPCI2CState *s)
|
||||
{
|
||||
return s->sr & CSR_MIF;
|
||||
}
|
||||
|
||||
static bool mpc_i2c_irq_is_enabled(MPCI2CState *s)
|
||||
{
|
||||
return s->cr & CCR_MIEN;
|
||||
}
|
||||
|
||||
static void mpc_i2c_reset(DeviceState *dev)
|
||||
{
|
||||
MPCI2CState *i2c = MPC_I2C(dev);
|
||||
|
||||
i2c->address = 0xFF;
|
||||
i2c->adr = 0x00;
|
||||
i2c->fdr = 0x00;
|
||||
i2c->cr = 0x00;
|
||||
i2c->sr = 0x81;
|
||||
i2c->dr = 0x00;
|
||||
}
|
||||
|
||||
static void mpc_i2c_irq(MPCI2CState *s)
|
||||
{
|
||||
bool irq_active = false;
|
||||
|
||||
if (mpc_i2c_is_enabled(s) && mpc_i2c_irq_is_enabled(s)
|
||||
&& mpc_i2c_irq_pending(s)) {
|
||||
irq_active = true;
|
||||
}
|
||||
|
||||
if (irq_active) {
|
||||
qemu_irq_raise(s->irq);
|
||||
} else {
|
||||
qemu_irq_lower(s->irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc_i2c_soft_reset(MPCI2CState *s)
|
||||
{
|
||||
/* This is a soft reset. ADR is preserved during soft resets */
|
||||
uint8_t adr = s->adr;
|
||||
mpc_i2c_reset(DEVICE(s));
|
||||
s->adr = adr;
|
||||
}
|
||||
|
||||
static void mpc_i2c_address_send(MPCI2CState *s)
|
||||
{
|
||||
/* if returns non zero slave address is not right */
|
||||
if (i2c_start_transfer(s->bus, s->dr >> 1, s->dr & (0x01))) {
|
||||
s->sr |= CSR_RXAK;
|
||||
} else {
|
||||
s->address = s->dr;
|
||||
s->sr &= ~CSR_RXAK;
|
||||
s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
|
||||
s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
|
||||
mpc_i2c_irq(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc_i2c_data_send(MPCI2CState *s)
|
||||
{
|
||||
if (i2c_send(s->bus, s->dr)) {
|
||||
/* End of transfer */
|
||||
s->sr |= CSR_RXAK;
|
||||
i2c_end_transfer(s->bus);
|
||||
} else {
|
||||
s->sr &= ~CSR_RXAK;
|
||||
s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
|
||||
s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
|
||||
mpc_i2c_irq(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void mpc_i2c_data_recive(MPCI2CState *s)
|
||||
{
|
||||
int ret;
|
||||
/* get the next byte */
|
||||
ret = i2c_recv(s->bus);
|
||||
if (ret >= 0) {
|
||||
s->sr |= CSR_MCF; /* Set after Byte Transfer is completed */
|
||||
s->sr |= CSR_MIF; /* Set after Byte Transfer is completed */
|
||||
mpc_i2c_irq(s);
|
||||
} else {
|
||||
DPRINTF("read failed for device");
|
||||
ret = 0xff;
|
||||
}
|
||||
s->dr = ret;
|
||||
}
|
||||
|
||||
static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
MPCI2CState *s = opaque;
|
||||
uint8_t value;
|
||||
|
||||
switch (addr) {
|
||||
case MPC_I2C_ADR:
|
||||
value = s->adr;
|
||||
break;
|
||||
case MPC_I2C_FDR:
|
||||
value = s->fdr;
|
||||
break;
|
||||
case MPC_I2C_CR:
|
||||
value = s->cr;
|
||||
break;
|
||||
case MPC_I2C_SR:
|
||||
value = s->sr;
|
||||
break;
|
||||
case MPC_I2C_DR:
|
||||
value = s->dr;
|
||||
if (mpc_i2c_is_master(s)) { /* master mode */
|
||||
if (mpc_i2c_direction_is_tx(s)) {
|
||||
DPRINTF("MTX is set not in recv mode\n");
|
||||
} else {
|
||||
mpc_i2c_data_recive(s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
value = 0;
|
||||
DPRINTF("ERROR: Bad read addr 0x%x\n", (unsigned int)addr);
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTF("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n", __func__,
|
||||
addr, value);
|
||||
return (uint64_t)value;
|
||||
}
|
||||
|
||||
static void mpc_i2c_write(void *opaque, hwaddr addr,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
MPCI2CState *s = opaque;
|
||||
|
||||
DPRINTF("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n", __func__,
|
||||
addr, value);
|
||||
switch (addr) {
|
||||
case MPC_I2C_ADR:
|
||||
s->adr = value & CADR_MASK;
|
||||
break;
|
||||
case MPC_I2C_FDR:
|
||||
s->fdr = value & CFDR_MASK;
|
||||
break;
|
||||
case MPC_I2C_CR:
|
||||
if (mpc_i2c_is_enabled(s) && ((value & CCR_MEN) == 0)) {
|
||||
mpc_i2c_soft_reset(s);
|
||||
break;
|
||||
}
|
||||
/* normal write */
|
||||
s->cr = value & CCR_MASK;
|
||||
if (mpc_i2c_is_master(s)) { /* master mode */
|
||||
/* set the bus to busy after master is set as per RM */
|
||||
s->sr |= CSR_MBB;
|
||||
} else {
|
||||
/* bus is not busy anymore */
|
||||
s->sr &= ~CSR_MBB;
|
||||
/* Reset the address for fresh write/read cycle */
|
||||
if (s->address != CYCLE_RESET) {
|
||||
i2c_end_transfer(s->bus);
|
||||
s->address = CYCLE_RESET;
|
||||
}
|
||||
}
|
||||
/* For restart end the onging transfer */
|
||||
if (s->cr & CCR_RSTA) {
|
||||
if (s->address != CYCLE_RESET) {
|
||||
s->address = CYCLE_RESET;
|
||||
i2c_end_transfer(s->bus);
|
||||
s->cr &= ~CCR_RSTA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MPC_I2C_SR:
|
||||
s->sr = value & CSR_MASK;
|
||||
/* Lower the interrupt */
|
||||
if (!(s->sr & CSR_MIF) || !(s->sr & CSR_MAL)) {
|
||||
mpc_i2c_irq(s);
|
||||
}
|
||||
break;
|
||||
case MPC_I2C_DR:
|
||||
/* if the device is not enabled, nothing to do */
|
||||
if (!mpc_i2c_is_enabled(s)) {
|
||||
break;
|
||||
}
|
||||
s->dr = value & CDR_MASK;
|
||||
if (mpc_i2c_is_master(s)) { /* master mode */
|
||||
if (s->address == CYCLE_RESET) {
|
||||
mpc_i2c_address_send(s);
|
||||
} else {
|
||||
mpc_i2c_data_send(s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MPC_I2C_DFSRR:
|
||||
s->dfssr = value;
|
||||
break;
|
||||
default:
|
||||
DPRINTF("ERROR: Bad write addr 0x%x\n", (unsigned int)addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps i2c_ops = {
|
||||
.read = mpc_i2c_read,
|
||||
.write = mpc_i2c_write,
|
||||
.valid.max_access_size = 1,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
static const VMStateDescription mpc_i2c_vmstate = {
|
||||
.name = TYPE_MPC_I2C,
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(address, MPCI2CState),
|
||||
VMSTATE_UINT8(adr, MPCI2CState),
|
||||
VMSTATE_UINT8(fdr, MPCI2CState),
|
||||
VMSTATE_UINT8(cr, MPCI2CState),
|
||||
VMSTATE_UINT8(sr, MPCI2CState),
|
||||
VMSTATE_UINT8(dr, MPCI2CState),
|
||||
VMSTATE_UINT8(dfssr, MPCI2CState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void mpc_i2c_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
MPCI2CState *i2c = MPC_I2C(dev);
|
||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &i2c->irq);
|
||||
memory_region_init_io(&i2c->iomem, OBJECT(i2c), &i2c_ops, i2c,
|
||||
"mpc-i2c", 0x14);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &i2c->iomem);
|
||||
i2c->bus = i2c_init_bus(DEVICE(dev), "i2c");
|
||||
}
|
||||
|
||||
static void mpc_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->vmsd = &mpc_i2c_vmstate ;
|
||||
dc->reset = mpc_i2c_reset;
|
||||
dc->realize = mpc_i2c_realize;
|
||||
dc->desc = "MPC I2C Controller";
|
||||
}
|
||||
|
||||
static const TypeInfo mpc_i2c_type_info = {
|
||||
.name = TYPE_MPC_I2C,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(MPCI2CState),
|
||||
.class_init = mpc_i2c_class_init,
|
||||
};
|
||||
|
||||
static void mpc_i2c_register_types(void)
|
||||
{
|
||||
type_register_static(&mpc_i2c_type_info);
|
||||
}
|
||||
|
||||
type_init(mpc_i2c_register_types)
|
@ -39,7 +39,7 @@ obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
|
||||
obj-$(CONFIG_XICS_KVM) += xics_kvm.o
|
||||
obj-$(CONFIG_XIVE) += xive.o
|
||||
obj-$(CONFIG_XIVE_SPAPR) += spapr_xive.o
|
||||
obj-$(CONFIG_POWERNV) += xics_pnv.o
|
||||
obj-$(CONFIG_POWERNV) += xics_pnv.o pnv_xive.o
|
||||
obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
|
||||
obj-$(CONFIG_S390_FLIC) += s390_flic.o
|
||||
obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
|
||||
|
1753
hw/intc/pnv_xive.c
Normal file
1753
hw/intc/pnv_xive.c
Normal file
File diff suppressed because it is too large
Load Diff
248
hw/intc/pnv_xive_regs.h
Normal file
248
hw/intc/pnv_xive_regs.h
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* QEMU PowerPC XIVE interrupt controller model
|
||||
*
|
||||
* Copyright (c) 2017-2018, IBM Corporation.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See the
|
||||
* COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef PPC_PNV_XIVE_REGS_H
|
||||
#define PPC_PNV_XIVE_REGS_H
|
||||
|
||||
/* IC register offsets 0x0 - 0x400 */
|
||||
#define CQ_SWI_CMD_HIST 0x020
|
||||
#define CQ_SWI_CMD_POLL 0x028
|
||||
#define CQ_SWI_CMD_BCAST 0x030
|
||||
#define CQ_SWI_CMD_ASSIGN 0x038
|
||||
#define CQ_SWI_CMD_BLK_UPD 0x040
|
||||
#define CQ_SWI_RSP 0x048
|
||||
#define CQ_CFG_PB_GEN 0x050
|
||||
#define CQ_INT_ADDR_OPT PPC_BITMASK(14, 15)
|
||||
#define CQ_MSGSND 0x058
|
||||
#define CQ_CNPM_SEL 0x078
|
||||
#define CQ_IC_BAR 0x080
|
||||
#define CQ_IC_BAR_VALID PPC_BIT(0)
|
||||
#define CQ_IC_BAR_64K PPC_BIT(1)
|
||||
#define CQ_TM1_BAR 0x90
|
||||
#define CQ_TM2_BAR 0x0a0
|
||||
#define CQ_TM_BAR_VALID PPC_BIT(0)
|
||||
#define CQ_TM_BAR_64K PPC_BIT(1)
|
||||
#define CQ_PC_BAR 0x0b0
|
||||
#define CQ_PC_BAR_VALID PPC_BIT(0)
|
||||
#define CQ_PC_BARM 0x0b8
|
||||
#define CQ_PC_BARM_MASK PPC_BITMASK(26, 38)
|
||||
#define CQ_VC_BAR 0x0c0
|
||||
#define CQ_VC_BAR_VALID PPC_BIT(0)
|
||||
#define CQ_VC_BARM 0x0c8
|
||||
#define CQ_VC_BARM_MASK PPC_BITMASK(21, 37)
|
||||
#define CQ_TAR 0x0f0
|
||||
#define CQ_TAR_TBL_AUTOINC PPC_BIT(0)
|
||||
#define CQ_TAR_TSEL PPC_BITMASK(12, 15)
|
||||
#define CQ_TAR_TSEL_BLK PPC_BIT(12)
|
||||
#define CQ_TAR_TSEL_MIG PPC_BIT(13)
|
||||
#define CQ_TAR_TSEL_VDT PPC_BIT(14)
|
||||
#define CQ_TAR_TSEL_EDT PPC_BIT(15)
|
||||
#define CQ_TAR_TSEL_INDEX PPC_BITMASK(26, 31)
|
||||
#define CQ_TDR 0x0f8
|
||||
#define CQ_TDR_VDT_VALID PPC_BIT(0)
|
||||
#define CQ_TDR_VDT_BLK PPC_BITMASK(11, 15)
|
||||
#define CQ_TDR_VDT_INDEX PPC_BITMASK(28, 31)
|
||||
#define CQ_TDR_EDT_TYPE PPC_BITMASK(0, 1)
|
||||
#define CQ_TDR_EDT_INVALID 0
|
||||
#define CQ_TDR_EDT_IPI 1
|
||||
#define CQ_TDR_EDT_EQ 2
|
||||
#define CQ_TDR_EDT_BLK PPC_BITMASK(12, 15)
|
||||
#define CQ_TDR_EDT_INDEX PPC_BITMASK(26, 31)
|
||||
#define CQ_PBI_CTL 0x100
|
||||
#define CQ_PBI_PC_64K PPC_BIT(5)
|
||||
#define CQ_PBI_VC_64K PPC_BIT(6)
|
||||
#define CQ_PBI_LNX_TRIG PPC_BIT(7)
|
||||
#define CQ_PBI_FORCE_TM_LOCAL PPC_BIT(22)
|
||||
#define CQ_PBO_CTL 0x108
|
||||
#define CQ_AIB_CTL 0x110
|
||||
#define CQ_RST_CTL 0x118
|
||||
#define CQ_FIRMASK 0x198
|
||||
#define CQ_FIRMASK_AND 0x1a0
|
||||
#define CQ_FIRMASK_OR 0x1a8
|
||||
|
||||
/* PC LBS1 register offsets 0x400 - 0x800 */
|
||||
#define PC_TCTXT_CFG 0x400
|
||||
#define PC_TCTXT_CFG_BLKGRP_EN PPC_BIT(0)
|
||||
#define PC_TCTXT_CFG_TARGET_EN PPC_BIT(1)
|
||||
#define PC_TCTXT_CFG_LGS_EN PPC_BIT(2)
|
||||
#define PC_TCTXT_CFG_STORE_ACK PPC_BIT(3)
|
||||
#define PC_TCTXT_CFG_HARD_CHIPID_BLK PPC_BIT(8)
|
||||
#define PC_TCTXT_CHIPID_OVERRIDE PPC_BIT(9)
|
||||
#define PC_TCTXT_CHIPID PPC_BITMASK(12, 15)
|
||||
#define PC_TCTXT_INIT_AGE PPC_BITMASK(30, 31)
|
||||
#define PC_TCTXT_TRACK 0x408
|
||||
#define PC_TCTXT_TRACK_EN PPC_BIT(0)
|
||||
#define PC_TCTXT_INDIR0 0x420
|
||||
#define PC_TCTXT_INDIR_VALID PPC_BIT(0)
|
||||
#define PC_TCTXT_INDIR_THRDID PPC_BITMASK(9, 15)
|
||||
#define PC_TCTXT_INDIR1 0x428
|
||||
#define PC_TCTXT_INDIR2 0x430
|
||||
#define PC_TCTXT_INDIR3 0x438
|
||||
#define PC_THREAD_EN_REG0 0x440
|
||||
#define PC_THREAD_EN_REG0_SET 0x448
|
||||
#define PC_THREAD_EN_REG0_CLR 0x450
|
||||
#define PC_THREAD_EN_REG1 0x460
|
||||
#define PC_THREAD_EN_REG1_SET 0x468
|
||||
#define PC_THREAD_EN_REG1_CLR 0x470
|
||||
#define PC_GLOBAL_CONFIG 0x480
|
||||
#define PC_GCONF_INDIRECT PPC_BIT(32)
|
||||
#define PC_GCONF_CHIPID_OVR PPC_BIT(40)
|
||||
#define PC_GCONF_CHIPID PPC_BITMASK(44, 47)
|
||||
#define PC_VSD_TABLE_ADDR 0x488
|
||||
#define PC_VSD_TABLE_DATA 0x490
|
||||
#define PC_AT_KILL 0x4b0
|
||||
#define PC_AT_KILL_VALID PPC_BIT(0)
|
||||
#define PC_AT_KILL_BLOCK_ID PPC_BITMASK(27, 31)
|
||||
#define PC_AT_KILL_OFFSET PPC_BITMASK(48, 60)
|
||||
#define PC_AT_KILL_MASK 0x4b8
|
||||
|
||||
/* PC LBS2 register offsets */
|
||||
#define PC_VPC_CACHE_ENABLE 0x708
|
||||
#define PC_VPC_CACHE_EN_MASK PPC_BITMASK(0, 31)
|
||||
#define PC_VPC_SCRUB_TRIG 0x710
|
||||
#define PC_VPC_SCRUB_MASK 0x718
|
||||
#define PC_SCRUB_VALID PPC_BIT(0)
|
||||
#define PC_SCRUB_WANT_DISABLE PPC_BIT(1)
|
||||
#define PC_SCRUB_WANT_INVAL PPC_BIT(2)
|
||||
#define PC_SCRUB_BLOCK_ID PPC_BITMASK(27, 31)
|
||||
#define PC_SCRUB_OFFSET PPC_BITMASK(45, 63)
|
||||
#define PC_VPC_CWATCH_SPEC 0x738
|
||||
#define PC_VPC_CWATCH_CONFLICT PPC_BIT(0)
|
||||
#define PC_VPC_CWATCH_FULL PPC_BIT(8)
|
||||
#define PC_VPC_CWATCH_BLOCKID PPC_BITMASK(27, 31)
|
||||
#define PC_VPC_CWATCH_OFFSET PPC_BITMASK(45, 63)
|
||||
#define PC_VPC_CWATCH_DAT0 0x740
|
||||
#define PC_VPC_CWATCH_DAT1 0x748
|
||||
#define PC_VPC_CWATCH_DAT2 0x750
|
||||
#define PC_VPC_CWATCH_DAT3 0x758
|
||||
#define PC_VPC_CWATCH_DAT4 0x760
|
||||
#define PC_VPC_CWATCH_DAT5 0x768
|
||||
#define PC_VPC_CWATCH_DAT6 0x770
|
||||
#define PC_VPC_CWATCH_DAT7 0x778
|
||||
|
||||
/* VC0 register offsets 0x800 - 0xFFF */
|
||||
#define VC_GLOBAL_CONFIG 0x800
|
||||
#define VC_GCONF_INDIRECT PPC_BIT(32)
|
||||
#define VC_VSD_TABLE_ADDR 0x808
|
||||
#define VC_VSD_TABLE_DATA 0x810
|
||||
#define VC_IVE_ISB_BLOCK_MODE 0x818
|
||||
#define VC_EQD_BLOCK_MODE 0x820
|
||||
#define VC_VPS_BLOCK_MODE 0x828
|
||||
#define VC_IRQ_CONFIG_IPI 0x840
|
||||
#define VC_IRQ_CONFIG_MEMB_EN PPC_BIT(45)
|
||||
#define VC_IRQ_CONFIG_MEMB_SZ PPC_BITMASK(46, 51)
|
||||
#define VC_IRQ_CONFIG_HW 0x848
|
||||
#define VC_IRQ_CONFIG_CASCADE1 0x850
|
||||
#define VC_IRQ_CONFIG_CASCADE2 0x858
|
||||
#define VC_IRQ_CONFIG_REDIST 0x860
|
||||
#define VC_IRQ_CONFIG_IPI_CASC 0x868
|
||||
#define VC_AIB_TX_ORDER_TAG2_REL_TF PPC_BIT(20)
|
||||
#define VC_AIB_TX_ORDER_TAG2 0x890
|
||||
#define VC_AT_MACRO_KILL 0x8b0
|
||||
#define VC_AT_MACRO_KILL_MASK 0x8b8
|
||||
#define VC_KILL_VALID PPC_BIT(0)
|
||||
#define VC_KILL_TYPE PPC_BITMASK(14, 15)
|
||||
#define VC_KILL_IRQ 0
|
||||
#define VC_KILL_IVC 1
|
||||
#define VC_KILL_SBC 2
|
||||
#define VC_KILL_EQD 3
|
||||
#define VC_KILL_BLOCK_ID PPC_BITMASK(27, 31)
|
||||
#define VC_KILL_OFFSET PPC_BITMASK(48, 60)
|
||||
#define VC_EQC_CACHE_ENABLE 0x908
|
||||
#define VC_EQC_CACHE_EN_MASK PPC_BITMASK(0, 15)
|
||||
#define VC_EQC_SCRUB_TRIG 0x910
|
||||
#define VC_EQC_SCRUB_MASK 0x918
|
||||
#define VC_EQC_CONFIG 0x920
|
||||
#define X_VC_EQC_CONFIG 0x214 /* XSCOM register */
|
||||
#define VC_EQC_CONF_SYNC_IPI PPC_BIT(32)
|
||||
#define VC_EQC_CONF_SYNC_HW PPC_BIT(33)
|
||||
#define VC_EQC_CONF_SYNC_ESC1 PPC_BIT(34)
|
||||
#define VC_EQC_CONF_SYNC_ESC2 PPC_BIT(35)
|
||||
#define VC_EQC_CONF_SYNC_REDI PPC_BIT(36)
|
||||
#define VC_EQC_CONF_EQP_INTERLEAVE PPC_BIT(38)
|
||||
#define VC_EQC_CONF_ENABLE_END_s_BIT PPC_BIT(39)
|
||||
#define VC_EQC_CONF_ENABLE_END_u_BIT PPC_BIT(40)
|
||||
#define VC_EQC_CONF_ENABLE_END_c_BIT PPC_BIT(41)
|
||||
#define VC_EQC_CONF_ENABLE_MORE_QSZ PPC_BIT(42)
|
||||
#define VC_EQC_CONF_SKIP_ESCALATE PPC_BIT(43)
|
||||
#define VC_EQC_CWATCH_SPEC 0x928
|
||||
#define VC_EQC_CWATCH_CONFLICT PPC_BIT(0)
|
||||
#define VC_EQC_CWATCH_FULL PPC_BIT(8)
|
||||
#define VC_EQC_CWATCH_BLOCKID PPC_BITMASK(28, 31)
|
||||
#define VC_EQC_CWATCH_OFFSET PPC_BITMASK(40, 63)
|
||||
#define VC_EQC_CWATCH_DAT0 0x930
|
||||
#define VC_EQC_CWATCH_DAT1 0x938
|
||||
#define VC_EQC_CWATCH_DAT2 0x940
|
||||
#define VC_EQC_CWATCH_DAT3 0x948
|
||||
#define VC_IVC_SCRUB_TRIG 0x990
|
||||
#define VC_IVC_SCRUB_MASK 0x998
|
||||
#define VC_SBC_SCRUB_TRIG 0xa10
|
||||
#define VC_SBC_SCRUB_MASK 0xa18
|
||||
#define VC_SCRUB_VALID PPC_BIT(0)
|
||||
#define VC_SCRUB_WANT_DISABLE PPC_BIT(1)
|
||||
#define VC_SCRUB_WANT_INVAL PPC_BIT(2) /* EQC and SBC only */
|
||||
#define VC_SCRUB_BLOCK_ID PPC_BITMASK(28, 31)
|
||||
#define VC_SCRUB_OFFSET PPC_BITMASK(40, 63)
|
||||
#define VC_IVC_CACHE_ENABLE 0x988
|
||||
#define VC_IVC_CACHE_EN_MASK PPC_BITMASK(0, 15)
|
||||
#define VC_SBC_CACHE_ENABLE 0xa08
|
||||
#define VC_SBC_CACHE_EN_MASK PPC_BITMASK(0, 15)
|
||||
#define VC_IVC_CACHE_SCRUB_TRIG 0x990
|
||||
#define VC_IVC_CACHE_SCRUB_MASK 0x998
|
||||
#define VC_SBC_CACHE_ENABLE 0xa08
|
||||
#define VC_SBC_CACHE_SCRUB_TRIG 0xa10
|
||||
#define VC_SBC_CACHE_SCRUB_MASK 0xa18
|
||||
#define VC_SBC_CONFIG 0xa20
|
||||
#define VC_SBC_CONF_CPLX_CIST PPC_BIT(44)
|
||||
#define VC_SBC_CONF_CIST_BOTH PPC_BIT(45)
|
||||
#define VC_SBC_CONF_NO_UPD_PRF PPC_BIT(59)
|
||||
|
||||
/* VC1 register offsets */
|
||||
|
||||
/* VSD Table address register definitions (shared) */
|
||||
#define VST_ADDR_AUTOINC PPC_BIT(0)
|
||||
#define VST_TABLE_SELECT PPC_BITMASK(13, 15)
|
||||
#define VST_TSEL_IVT 0
|
||||
#define VST_TSEL_SBE 1
|
||||
#define VST_TSEL_EQDT 2
|
||||
#define VST_TSEL_VPDT 3
|
||||
#define VST_TSEL_IRQ 4 /* VC only */
|
||||
#define VST_TABLE_BLOCK PPC_BITMASK(27, 31)
|
||||
|
||||
/* Number of queue overflow pages */
|
||||
#define VC_QUEUE_OVF_COUNT 6
|
||||
|
||||
/*
|
||||
* Bits in a VSD entry.
|
||||
*
|
||||
* Note: the address is naturally aligned, we don't use a PPC_BITMASK,
|
||||
* but just a mask to apply to the address before OR'ing it in.
|
||||
*
|
||||
* Note: VSD_FIRMWARE is a SW bit ! It hijacks an unused bit in the
|
||||
* VSD and is only meant to be used in indirect mode !
|
||||
*/
|
||||
#define VSD_MODE PPC_BITMASK(0, 1)
|
||||
#define VSD_MODE_SHARED 1
|
||||
#define VSD_MODE_EXCLUSIVE 2
|
||||
#define VSD_MODE_FORWARD 3
|
||||
#define VSD_ADDRESS_MASK 0x0ffffffffffff000ull
|
||||
#define VSD_MIGRATION_REG PPC_BITMASK(52, 55)
|
||||
#define VSD_INDIRECT PPC_BIT(56)
|
||||
#define VSD_TSIZE PPC_BITMASK(59, 63)
|
||||
#define VSD_FIRMWARE PPC_BIT(2) /* Read warning above */
|
||||
|
||||
#define VC_EQC_SYNC_MASK \
|
||||
(VC_EQC_CONF_SYNC_IPI | \
|
||||
VC_EQC_CONF_SYNC_HW | \
|
||||
VC_EQC_CONF_SYNC_ESC1 | \
|
||||
VC_EQC_CONF_SYNC_ESC2 | \
|
||||
VC_EQC_CONF_SYNC_REDI)
|
||||
|
||||
|
||||
#endif /* PPC_PNV_XIVE_REGS_H */
|
@ -117,7 +117,7 @@ static int spapr_xive_target_to_end(uint32_t target, uint8_t prio,
|
||||
* On sPAPR machines, use a simplified output for the XIVE END
|
||||
* structure dumping only the information related to the OS EQ.
|
||||
*/
|
||||
static void spapr_xive_end_pic_print_info(sPAPRXive *xive, XiveEND *end,
|
||||
static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end,
|
||||
Monitor *mon)
|
||||
{
|
||||
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
|
||||
@ -135,7 +135,7 @@ static void spapr_xive_end_pic_print_info(sPAPRXive *xive, XiveEND *end,
|
||||
monitor_printf(mon, "]");
|
||||
}
|
||||
|
||||
void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon)
|
||||
void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
|
||||
{
|
||||
XiveSource *xsrc = &xive->source;
|
||||
int i;
|
||||
@ -173,14 +173,14 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon)
|
||||
}
|
||||
}
|
||||
|
||||
static void spapr_xive_map_mmio(sPAPRXive *xive)
|
||||
static void spapr_xive_map_mmio(SpaprXive *xive)
|
||||
{
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
|
||||
}
|
||||
|
||||
void spapr_xive_mmio_set_enabled(sPAPRXive *xive, bool enable)
|
||||
void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
|
||||
{
|
||||
memory_region_set_enabled(&xive->source.esb_mmio, enable);
|
||||
memory_region_set_enabled(&xive->tm_mmio, enable);
|
||||
@ -216,7 +216,7 @@ static void spapr_xive_end_reset(XiveEND *end)
|
||||
|
||||
static void spapr_xive_reset(void *dev)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(dev);
|
||||
SpaprXive *xive = SPAPR_XIVE(dev);
|
||||
int i;
|
||||
|
||||
/*
|
||||
@ -242,7 +242,7 @@ static void spapr_xive_reset(void *dev)
|
||||
|
||||
static void spapr_xive_instance_init(Object *obj)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(obj);
|
||||
SpaprXive *xive = SPAPR_XIVE(obj);
|
||||
|
||||
object_initialize_child(obj, "source", &xive->source, sizeof(xive->source),
|
||||
TYPE_XIVE_SOURCE, &error_abort, NULL);
|
||||
@ -254,7 +254,7 @@ static void spapr_xive_instance_init(Object *obj)
|
||||
|
||||
static void spapr_xive_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(dev);
|
||||
SpaprXive *xive = SPAPR_XIVE(dev);
|
||||
XiveSource *xsrc = &xive->source;
|
||||
XiveENDSource *end_xsrc = &xive->end_source;
|
||||
Error *local_err = NULL;
|
||||
@ -325,7 +325,7 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp)
|
||||
static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
|
||||
uint32_t eas_idx, XiveEAS *eas)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(xrtr);
|
||||
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
||||
|
||||
if (eas_idx >= xive->nr_irqs) {
|
||||
return -1;
|
||||
@ -338,7 +338,7 @@ static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
|
||||
static int spapr_xive_get_end(XiveRouter *xrtr,
|
||||
uint8_t end_blk, uint32_t end_idx, XiveEND *end)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(xrtr);
|
||||
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
||||
|
||||
if (end_idx >= xive->nr_ends) {
|
||||
return -1;
|
||||
@ -352,7 +352,7 @@ static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t end_blk,
|
||||
uint32_t end_idx, XiveEND *end,
|
||||
uint8_t word_number)
|
||||
{
|
||||
sPAPRXive *xive = SPAPR_XIVE(xrtr);
|
||||
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
||||
|
||||
if (end_idx >= xive->nr_ends) {
|
||||
return -1;
|
||||
@ -432,20 +432,20 @@ static const VMStateDescription vmstate_spapr_xive = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, sPAPRXive, nr_irqs,
|
||||
VMSTATE_UINT32_EQUAL(nr_irqs, SpaprXive, NULL),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, SpaprXive, nr_irqs,
|
||||
vmstate_spapr_xive_eas, XiveEAS),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, sPAPRXive, nr_ends,
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, SpaprXive, nr_ends,
|
||||
vmstate_spapr_xive_end, XiveEND),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static Property spapr_xive_properties[] = {
|
||||
DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0),
|
||||
DEFINE_PROP_UINT32("nr-ends", sPAPRXive, nr_ends, 0),
|
||||
DEFINE_PROP_UINT64("vc-base", sPAPRXive, vc_base, SPAPR_XIVE_VC_BASE),
|
||||
DEFINE_PROP_UINT64("tm-base", sPAPRXive, tm_base, SPAPR_XIVE_TM_BASE),
|
||||
DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
|
||||
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
|
||||
DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
|
||||
DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@ -471,7 +471,7 @@ static const TypeInfo spapr_xive_info = {
|
||||
.name = TYPE_SPAPR_XIVE,
|
||||
.parent = TYPE_XIVE_ROUTER,
|
||||
.instance_init = spapr_xive_instance_init,
|
||||
.instance_size = sizeof(sPAPRXive),
|
||||
.instance_size = sizeof(SpaprXive),
|
||||
.class_init = spapr_xive_class_init,
|
||||
};
|
||||
|
||||
@ -482,7 +482,7 @@ static void spapr_xive_register_types(void)
|
||||
|
||||
type_init(spapr_xive_register_types)
|
||||
|
||||
bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi)
|
||||
bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi)
|
||||
{
|
||||
XiveSource *xsrc = &xive->source;
|
||||
|
||||
@ -497,7 +497,7 @@ bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn)
|
||||
bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn)
|
||||
{
|
||||
if (lisn >= xive->nr_irqs) {
|
||||
return false;
|
||||
@ -576,11 +576,11 @@ static bool spapr_xive_priority_is_reserved(uint8_t priority)
|
||||
#define SPAPR_XIVE_SRC_STORE_EOI PPC_BIT(63) /* Store EOI support */
|
||||
|
||||
static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
XiveSource *xsrc = &xive->source;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong lisn = args[1];
|
||||
@ -686,11 +686,11 @@ static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
|
||||
#define SPAPR_XIVE_SRC_MASK PPC_BIT(63)
|
||||
|
||||
static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
XiveEAS eas, new_eas;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong lisn = args[1];
|
||||
@ -783,11 +783,11 @@ out:
|
||||
* equivalent to the LISN if not changed by H_INT_SET_SOURCE_CONFIG)
|
||||
*/
|
||||
static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong lisn = args[1];
|
||||
XiveEAS eas;
|
||||
@ -856,11 +856,11 @@ static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
|
||||
* - R5: Power of 2 page size of the notification page
|
||||
*/
|
||||
static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
XiveENDSource *end_xsrc = &xive->end_source;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong target = args[1];
|
||||
@ -942,11 +942,11 @@ static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
|
||||
#define SPAPR_XIVE_END_ALWAYS_NOTIFY PPC_BIT(63)
|
||||
|
||||
static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong target = args[1];
|
||||
target_ulong priority = args[2];
|
||||
@ -1095,11 +1095,11 @@ out:
|
||||
#define SPAPR_XIVE_END_DEBUG PPC_BIT(63)
|
||||
|
||||
static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong target = args[1];
|
||||
target_ulong priority = args[2];
|
||||
@ -1187,7 +1187,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
|
||||
* - None
|
||||
*/
|
||||
static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1223,7 +1223,7 @@ static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
|
||||
* - R4: The logical real address of the reporting line if set, else -1
|
||||
*/
|
||||
static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1266,11 +1266,11 @@ static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
|
||||
#define SPAPR_XIVE_ESB_STORE PPC_BIT(63)
|
||||
|
||||
static target_ulong h_int_esb(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
XiveEAS eas;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong lisn = args[1];
|
||||
@ -1334,11 +1334,11 @@ static target_ulong h_int_esb(PowerPCCPU *cpu,
|
||||
* - None
|
||||
*/
|
||||
static target_ulong h_int_sync(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
XiveEAS eas;
|
||||
target_ulong flags = args[0];
|
||||
target_ulong lisn = args[1];
|
||||
@ -1388,11 +1388,11 @@ static target_ulong h_int_sync(PowerPCCPU *cpu,
|
||||
* - None
|
||||
*/
|
||||
static target_ulong h_int_reset(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
target_ulong flags = args[0];
|
||||
|
||||
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
||||
@ -1407,7 +1407,7 @@ static target_ulong h_int_reset(PowerPCCPU *cpu,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
void spapr_xive_hcall_init(sPAPRMachineState *spapr)
|
||||
void spapr_xive_hcall_init(SpaprMachineState *spapr)
|
||||
{
|
||||
spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info);
|
||||
spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_config);
|
||||
@ -1424,10 +1424,10 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr)
|
||||
spapr_register_hypercall(H_INT_RESET, h_int_reset);
|
||||
}
|
||||
|
||||
void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
int node;
|
||||
uint64_t timas[2 * 2];
|
||||
/* Interrupt number ranges for the IPIs */
|
||||
|
@ -291,7 +291,7 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val)
|
||||
}
|
||||
}
|
||||
|
||||
static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -300,7 +300,7 @@ static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
__func__);
|
||||
}
|
||||
|
||||
int xics_kvm_init(sPAPRMachineState *spapr, Error **errp)
|
||||
int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
* Guest interfaces
|
||||
*/
|
||||
|
||||
static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong cppr = args[0];
|
||||
@ -50,7 +50,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_ipi(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong mfrr = args[1];
|
||||
@ -64,7 +64,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_xirr(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
|
||||
@ -73,7 +73,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_xirr_x(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
|
||||
@ -83,7 +83,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_eoi(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong xirr = args[0];
|
||||
@ -92,7 +92,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_ipoll(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
uint32_t mfrr;
|
||||
@ -104,7 +104,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -137,7 +137,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_get_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -167,7 +167,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 2, ics->irqs[srcno].priority);
|
||||
}
|
||||
|
||||
static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_int_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -198,7 +198,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_int_on(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -230,7 +230,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
void xics_spapr_init(sPAPRMachineState *spapr)
|
||||
void xics_spapr_init(SpaprMachineState *spapr)
|
||||
{
|
||||
/* Registration of global state belongs into realize */
|
||||
spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
|
||||
@ -246,7 +246,7 @@ void xics_spapr_init(sPAPRMachineState *spapr)
|
||||
spapr_register_hypercall(H_IPOLL, h_ipoll);
|
||||
}
|
||||
|
||||
void spapr_dt_xics(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle)
|
||||
{
|
||||
uint32_t interrupt_server_ranges_prop[] = {
|
||||
|
113
hw/intc/xive.c
113
hw/intc/xive.c
@ -54,6 +54,8 @@ static uint8_t exception_mask(uint8_t ring)
|
||||
switch (ring) {
|
||||
case TM_QW1_OS:
|
||||
return TM_QW1_NSR_EO;
|
||||
case TM_QW3_HV_PHYS:
|
||||
return TM_QW3_NSR_HE;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@ -88,7 +90,16 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
|
||||
uint8_t *regs = &tctx->regs[ring];
|
||||
|
||||
if (regs[TM_PIPR] < regs[TM_CPPR]) {
|
||||
regs[TM_NSR] |= exception_mask(ring);
|
||||
switch (ring) {
|
||||
case TM_QW1_OS:
|
||||
regs[TM_NSR] |= TM_QW1_NSR_EO;
|
||||
break;
|
||||
case TM_QW3_HV_PHYS:
|
||||
regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
qemu_irq_raise(tctx->output);
|
||||
}
|
||||
}
|
||||
@ -109,6 +120,38 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
|
||||
* XIVE Thread Interrupt Management Area (TIMA)
|
||||
*/
|
||||
|
||||
static void xive_tm_set_hv_cppr(XiveTCTX *tctx, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
xive_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff);
|
||||
}
|
||||
|
||||
static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr offset, unsigned size)
|
||||
{
|
||||
return xive_tctx_accept(tctx, TM_QW3_HV_PHYS);
|
||||
}
|
||||
|
||||
static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
|
||||
unsigned size)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
|
||||
tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = value & 0xff;
|
||||
}
|
||||
|
||||
static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr offset, unsigned size)
|
||||
{
|
||||
return tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define an access map for each page of the TIMA that we will use in
|
||||
* the memory region ops to filter values when doing loads and stores
|
||||
@ -288,10 +331,16 @@ static const XiveTmOp xive_tm_operations[] = {
|
||||
* effects
|
||||
*/
|
||||
{ XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, NULL },
|
||||
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, NULL },
|
||||
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL },
|
||||
{ XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll },
|
||||
|
||||
/* MMIOs above 2K : special operations with side effects */
|
||||
{ XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg },
|
||||
{ XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL },
|
||||
{ XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg },
|
||||
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx },
|
||||
{ XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx },
|
||||
};
|
||||
|
||||
static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
|
||||
@ -317,14 +366,13 @@ static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
|
||||
/*
|
||||
* TIMA MMIO handlers
|
||||
*/
|
||||
static void xive_tm_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
|
||||
unsigned size)
|
||||
{
|
||||
XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
|
||||
const XiveTmOp *xto;
|
||||
|
||||
/*
|
||||
* TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU
|
||||
* TODO: check V bit in Q[0-3]W2
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -356,13 +404,12 @@ static void xive_tm_write(void *opaque, hwaddr offset,
|
||||
xive_tm_raw_write(tctx, offset, value, size);
|
||||
}
|
||||
|
||||
static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
|
||||
uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
|
||||
{
|
||||
XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
|
||||
const XiveTmOp *xto;
|
||||
|
||||
/*
|
||||
* TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU
|
||||
* TODO: check V bit in Q[0-3]W2
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -392,6 +439,21 @@ static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
|
||||
return xive_tm_raw_read(tctx, offset, size);
|
||||
}
|
||||
|
||||
static void xive_tm_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
|
||||
|
||||
xive_tctx_tm_write(tctx, offset, value, size);
|
||||
}
|
||||
|
||||
static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
XiveTCTX *tctx = xive_router_get_tctx(XIVE_ROUTER(opaque), current_cpu);
|
||||
|
||||
return xive_tctx_tm_read(tctx, offset, size);
|
||||
}
|
||||
|
||||
const MemoryRegionOps xive_tm_ops = {
|
||||
.read = xive_tm_read,
|
||||
.write = xive_tm_write,
|
||||
@ -459,6 +521,8 @@ static void xive_tctx_reset(void *dev)
|
||||
*/
|
||||
tctx->regs[TM_QW1_OS + TM_PIPR] =
|
||||
ipb_to_pipr(tctx->regs[TM_QW1_OS + TM_IPB]);
|
||||
tctx->regs[TM_QW3_HV_PHYS + TM_PIPR] =
|
||||
ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]);
|
||||
}
|
||||
|
||||
static void xive_tctx_realize(DeviceState *dev, Error **errp)
|
||||
@ -1112,6 +1176,30 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs)
|
||||
return xrc->get_tctx(xrtr, cs);
|
||||
}
|
||||
|
||||
/*
|
||||
* By default on P9, the HW CAM line (23bits) is hardwired to :
|
||||
*
|
||||
* 0x000||0b1||4Bit chip number||7Bit Thread number.
|
||||
*
|
||||
* When the block grouping is enabled, the CAM line is changed to :
|
||||
*
|
||||
* 4Bit chip number||0x001||7Bit Thread number.
|
||||
*/
|
||||
static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
|
||||
{
|
||||
return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
|
||||
}
|
||||
|
||||
static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
|
||||
uint8_t nvt_blk, uint32_t nvt_idx)
|
||||
{
|
||||
CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
|
||||
uint32_t pir = env->spr_cb[SPR_PIR].default_value;
|
||||
|
||||
return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
|
||||
hw_cam_line(nvt_blk, nvt_idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* The thread context register words are in big-endian format.
|
||||
*/
|
||||
@ -1120,6 +1208,7 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
|
||||
bool cam_ignore, uint32_t logic_serv)
|
||||
{
|
||||
uint32_t cam = xive_nvt_cam_line(nvt_blk, nvt_idx);
|
||||
uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]);
|
||||
uint32_t qw2w2 = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
|
||||
uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]);
|
||||
uint32_t qw0w2 = xive_tctx_word2(&tctx->regs[TM_QW0_USER]);
|
||||
@ -1142,7 +1231,11 @@ static int xive_presenter_tctx_match(XiveTCTX *tctx, uint8_t format,
|
||||
|
||||
/* F=0 & i=0: Specific NVT notification */
|
||||
|
||||
/* TODO (PowerNV) : PHYS ring */
|
||||
/* PHYS ring */
|
||||
if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
|
||||
xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
|
||||
return TM_QW3_HV_PHYS;
|
||||
}
|
||||
|
||||
/* HV POOL ring */
|
||||
if ((be32_to_cpu(qw2w2) & TM_QW2W2_VP) &&
|
||||
@ -1362,7 +1455,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk,
|
||||
/* TODO: Auto EOI. */
|
||||
}
|
||||
|
||||
static void xive_router_notify(XiveNotifier *xn, uint32_t lisn)
|
||||
void xive_router_notify(XiveNotifier *xn, uint32_t lisn)
|
||||
{
|
||||
XiveRouter *xrtr = XIVE_ROUTER(xn);
|
||||
uint8_t eas_blk = XIVE_SRCNO_BLOCK(lisn);
|
||||
|
@ -84,7 +84,7 @@ typedef uint64_t vlan_bd_t;
|
||||
|
||||
#define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
|
||||
#define VIO_SPAPR_VLAN_DEVICE(obj) \
|
||||
OBJECT_CHECK(VIOsPAPRVLANDevice, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)
|
||||
OBJECT_CHECK(SpaprVioVlan, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)
|
||||
|
||||
#define RX_POOL_MAX_BDS 4096
|
||||
#define RX_MAX_POOLS 5
|
||||
@ -95,8 +95,8 @@ typedef struct {
|
||||
vlan_bd_t bds[RX_POOL_MAX_BDS];
|
||||
} RxBufPool;
|
||||
|
||||
typedef struct VIOsPAPRVLANDevice {
|
||||
VIOsPAPRDevice sdev;
|
||||
typedef struct SpaprVioVlan {
|
||||
SpaprVioDevice sdev;
|
||||
NICConf nicconf;
|
||||
NICState *nic;
|
||||
MACAddr perm_mac;
|
||||
@ -107,11 +107,11 @@ typedef struct VIOsPAPRVLANDevice {
|
||||
QEMUTimer *rxp_timer;
|
||||
uint32_t compat_flags; /* Compatibility flags for migration */
|
||||
RxBufPool *rx_pool[RX_MAX_POOLS]; /* Receive buffer descriptor pools */
|
||||
} VIOsPAPRVLANDevice;
|
||||
} SpaprVioVlan;
|
||||
|
||||
static int spapr_vlan_can_receive(NetClientState *nc)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
|
||||
SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
|
||||
|
||||
return (dev->isopen && dev->rx_bufs > 0);
|
||||
}
|
||||
@ -123,7 +123,7 @@ static int spapr_vlan_can_receive(NetClientState *nc)
|
||||
* suitable receive buffer available. This function is used to increase
|
||||
* this counter by one.
|
||||
*/
|
||||
static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
|
||||
static void spapr_vlan_record_dropped_rx_frame(SpaprVioVlan *dev)
|
||||
{
|
||||
uint64_t cnt;
|
||||
|
||||
@ -134,7 +134,7 @@ static void spapr_vlan_record_dropped_rx_frame(VIOsPAPRVLANDevice *dev)
|
||||
/**
|
||||
* Get buffer descriptor from one of our receive buffer pools
|
||||
*/
|
||||
static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
|
||||
static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(SpaprVioVlan *dev,
|
||||
size_t size)
|
||||
{
|
||||
vlan_bd_t bd;
|
||||
@ -168,7 +168,7 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
|
||||
* Get buffer descriptor from the receive buffer list page that has been
|
||||
* supplied by the guest with the H_REGISTER_LOGICAL_LAN call
|
||||
*/
|
||||
static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
|
||||
static vlan_bd_t spapr_vlan_get_rx_bd_from_page(SpaprVioVlan *dev,
|
||||
size_t size)
|
||||
{
|
||||
int buf_ptr = dev->use_buf_ptr;
|
||||
@ -203,8 +203,8 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
|
||||
static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
size_t size)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = qemu_get_nic_opaque(nc);
|
||||
VIOsPAPRDevice *sdev = VIO_SPAPR_DEVICE(dev);
|
||||
SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
|
||||
SpaprVioDevice *sdev = VIO_SPAPR_DEVICE(dev);
|
||||
vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
|
||||
vlan_bd_t bd;
|
||||
uint64_t handle;
|
||||
@ -280,7 +280,7 @@ static NetClientInfo net_spapr_vlan_info = {
|
||||
|
||||
static void spapr_vlan_flush_rx_queue(void *opaque)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = opaque;
|
||||
SpaprVioVlan *dev = opaque;
|
||||
|
||||
qemu_flush_queued_packets(qemu_get_queue(dev->nic));
|
||||
}
|
||||
@ -296,9 +296,9 @@ static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
|
||||
memset(rxp->bds, 0, sizeof(rxp->bds));
|
||||
}
|
||||
|
||||
static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
|
||||
static void spapr_vlan_reset(SpaprVioDevice *sdev)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
int i;
|
||||
|
||||
dev->buf_list = 0;
|
||||
@ -316,9 +316,9 @@ static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
|
||||
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
|
||||
}
|
||||
|
||||
static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
|
||||
static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
|
||||
qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
|
||||
|
||||
@ -334,7 +334,7 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
|
||||
|
||||
static void spapr_vlan_instance_init(Object *obj)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
|
||||
int i;
|
||||
|
||||
device_add_bootindex_property(obj, &dev->nicconf.bootindex,
|
||||
@ -351,7 +351,7 @@ static void spapr_vlan_instance_init(Object *obj)
|
||||
|
||||
static void spapr_vlan_instance_finalize(Object *obj)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
|
||||
int i;
|
||||
|
||||
if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
|
||||
@ -367,7 +367,7 @@ static void spapr_vlan_instance_finalize(Object *obj)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
|
||||
void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd)
|
||||
{
|
||||
DeviceState *dev;
|
||||
|
||||
@ -378,9 +378,9 @@ void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
|
||||
qdev_init_nofail(dev);
|
||||
}
|
||||
|
||||
static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||
static int spapr_vlan_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
|
||||
{
|
||||
VIOsPAPRVLANDevice *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
|
||||
SpaprVioVlan *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
|
||||
uint8_t padded_mac[8] = {0, 0};
|
||||
int ret;
|
||||
|
||||
@ -415,7 +415,7 @@ static int spapr_vlan_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
|
||||
static int check_bd(SpaprVioVlan *dev, vlan_bd_t bd,
|
||||
target_ulong alignment)
|
||||
{
|
||||
if ((VLAN_BD_ADDR(bd) % alignment)
|
||||
@ -434,7 +434,7 @@ static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd,
|
||||
}
|
||||
|
||||
static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -442,8 +442,8 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
|
||||
target_ulong buf_list = args[1];
|
||||
target_ulong rec_queue = args[2];
|
||||
target_ulong filter_list = args[3];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
vlan_bd_t filter_list_bd;
|
||||
|
||||
if (!dev) {
|
||||
@ -500,12 +500,12 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
|
||||
|
||||
|
||||
static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
|
||||
if (!dev) {
|
||||
return H_PARAMETER;
|
||||
@ -539,7 +539,7 @@ static int rx_pool_size_compare(const void *p1, const void *p2)
|
||||
* Search for a matching buffer pool with exact matching size,
|
||||
* or return -1 if no matching pool has been found.
|
||||
*/
|
||||
static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size)
|
||||
static int spapr_vlan_get_rx_pool_id(SpaprVioVlan *dev, int size)
|
||||
{
|
||||
int pool;
|
||||
|
||||
@ -555,7 +555,7 @@ static int spapr_vlan_get_rx_pool_id(VIOsPAPRVLANDevice *dev, int size)
|
||||
/**
|
||||
* Enqueuing receive buffer by adding it to one of our receive buffer pools
|
||||
*/
|
||||
static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
|
||||
static target_long spapr_vlan_add_rxbuf_to_pool(SpaprVioVlan *dev,
|
||||
target_ulong buf)
|
||||
{
|
||||
int size = VLAN_BD_LEN(buf);
|
||||
@ -602,7 +602,7 @@ static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
|
||||
* This is the old way of enqueuing receive buffers: Add it to the rx queue
|
||||
* page that has been supplied by the guest (which is quite limited in size).
|
||||
*/
|
||||
static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
|
||||
static target_long spapr_vlan_add_rxbuf_to_page(SpaprVioVlan *dev,
|
||||
target_ulong buf)
|
||||
{
|
||||
vlan_bd_t bd;
|
||||
@ -628,14 +628,14 @@ static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
|
||||
}
|
||||
|
||||
static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong buf = args[1];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
target_long ret;
|
||||
|
||||
trace_spapr_vlan_h_add_logical_lan_buffer(reg, buf);
|
||||
@ -678,14 +678,14 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong *bufs = args + 1;
|
||||
target_ulong continue_token = args[7];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
unsigned total_len;
|
||||
uint8_t *lbuf, *p;
|
||||
int i, nbufs;
|
||||
@ -745,11 +745,11 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
|
||||
if (!dev) {
|
||||
return H_PARAMETER;
|
||||
@ -759,14 +759,14 @@ static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
|
||||
static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong macaddr = args[1];
|
||||
VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
@ -780,16 +780,16 @@ static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static Property spapr_vlan_properties[] = {
|
||||
DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev),
|
||||
DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
|
||||
DEFINE_PROP_BIT("use-rx-buffer-pools", VIOsPAPRVLANDevice,
|
||||
DEFINE_SPAPR_PROPERTIES(SpaprVioVlan, sdev),
|
||||
DEFINE_NIC_PROPERTIES(SpaprVioVlan, nicconf),
|
||||
DEFINE_PROP_BIT("use-rx-buffer-pools", SpaprVioVlan,
|
||||
compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static bool spapr_vlan_rx_buffer_pools_needed(void *opaque)
|
||||
{
|
||||
VIOsPAPRVLANDevice *dev = opaque;
|
||||
SpaprVioVlan *dev = opaque;
|
||||
|
||||
return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0;
|
||||
}
|
||||
@ -813,7 +813,7 @@ static const VMStateDescription vmstate_rx_pools = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_vlan_rx_buffer_pools_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, VIOsPAPRVLANDevice,
|
||||
VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, SpaprVioVlan,
|
||||
RX_MAX_POOLS, 1,
|
||||
vmstate_rx_buffer_pool, RxBufPool),
|
||||
VMSTATE_END_OF_LIST()
|
||||
@ -825,14 +825,14 @@ static const VMStateDescription vmstate_spapr_llan = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVLANDevice),
|
||||
VMSTATE_SPAPR_VIO(sdev, SpaprVioVlan),
|
||||
/* LLAN state */
|
||||
VMSTATE_BOOL(isopen, VIOsPAPRVLANDevice),
|
||||
VMSTATE_UINT64(buf_list, VIOsPAPRVLANDevice),
|
||||
VMSTATE_UINT32(add_buf_ptr, VIOsPAPRVLANDevice),
|
||||
VMSTATE_UINT32(use_buf_ptr, VIOsPAPRVLANDevice),
|
||||
VMSTATE_UINT32(rx_bufs, VIOsPAPRVLANDevice),
|
||||
VMSTATE_UINT64(rxq_ptr, VIOsPAPRVLANDevice),
|
||||
VMSTATE_BOOL(isopen, SpaprVioVlan),
|
||||
VMSTATE_UINT64(buf_list, SpaprVioVlan),
|
||||
VMSTATE_UINT32(add_buf_ptr, SpaprVioVlan),
|
||||
VMSTATE_UINT32(use_buf_ptr, SpaprVioVlan),
|
||||
VMSTATE_UINT32(rx_bufs, SpaprVioVlan),
|
||||
VMSTATE_UINT64(rxq_ptr, SpaprVioVlan),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
@ -845,7 +845,7 @@ static const VMStateDescription vmstate_spapr_llan = {
|
||||
static void spapr_vlan_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = spapr_vlan_realize;
|
||||
k->reset = spapr_vlan_reset;
|
||||
@ -863,7 +863,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
|
||||
static const TypeInfo spapr_vlan_info = {
|
||||
.name = TYPE_VIO_SPAPR_VLAN_DEVICE,
|
||||
.parent = TYPE_VIO_SPAPR_DEVICE,
|
||||
.instance_size = sizeof(VIOsPAPRVLANDevice),
|
||||
.instance_size = sizeof(SpaprVioVlan),
|
||||
.class_init = spapr_vlan_class_init,
|
||||
.instance_init = spapr_vlan_instance_init,
|
||||
.instance_finalize = spapr_vlan_instance_finalize,
|
||||
|
@ -36,28 +36,28 @@
|
||||
#include "hw/ppc/spapr.h"
|
||||
#include "hw/ppc/spapr_vio.h"
|
||||
|
||||
typedef struct sPAPRNVRAM {
|
||||
VIOsPAPRDevice sdev;
|
||||
typedef struct SpaprNvram {
|
||||
SpaprVioDevice sdev;
|
||||
uint32_t size;
|
||||
uint8_t *buf;
|
||||
BlockBackend *blk;
|
||||
VMChangeStateEntry *vmstate;
|
||||
} sPAPRNVRAM;
|
||||
} SpaprNvram;
|
||||
|
||||
#define TYPE_VIO_SPAPR_NVRAM "spapr-nvram"
|
||||
#define VIO_SPAPR_NVRAM(obj) \
|
||||
OBJECT_CHECK(sPAPRNVRAM, (obj), TYPE_VIO_SPAPR_NVRAM)
|
||||
OBJECT_CHECK(SpaprNvram, (obj), TYPE_VIO_SPAPR_NVRAM)
|
||||
|
||||
#define MIN_NVRAM_SIZE (8 * KiB)
|
||||
#define DEFAULT_NVRAM_SIZE (64 * KiB)
|
||||
#define MAX_NVRAM_SIZE (1 * MiB)
|
||||
|
||||
static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_nvram_fetch(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRNVRAM *nvram = spapr->nvram;
|
||||
SpaprNvram *nvram = spapr->nvram;
|
||||
hwaddr offset, buffer, len;
|
||||
void *membuf;
|
||||
|
||||
@ -93,12 +93,12 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 1, len);
|
||||
}
|
||||
|
||||
static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_nvram_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRNVRAM *nvram = spapr->nvram;
|
||||
SpaprNvram *nvram = spapr->nvram;
|
||||
hwaddr offset, buffer, len;
|
||||
int alen;
|
||||
void *membuf;
|
||||
@ -139,9 +139,9 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
|
||||
}
|
||||
|
||||
static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error **errp)
|
||||
static void spapr_nvram_realize(SpaprVioDevice *dev, Error **errp)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
|
||||
SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
|
||||
int ret;
|
||||
|
||||
if (nvram->blk) {
|
||||
@ -193,16 +193,16 @@ static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error **errp)
|
||||
spapr_rtas_register(RTAS_NVRAM_STORE, "nvram-store", rtas_nvram_store);
|
||||
}
|
||||
|
||||
static int spapr_nvram_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||
static int spapr_nvram_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
|
||||
SpaprNvram *nvram = VIO_SPAPR_NVRAM(dev);
|
||||
|
||||
return fdt_setprop_cell(fdt, node_off, "#bytes", nvram->size);
|
||||
}
|
||||
|
||||
static int spapr_nvram_pre_load(void *opaque)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
|
||||
g_free(nvram->buf);
|
||||
nvram->buf = NULL;
|
||||
@ -213,7 +213,7 @@ static int spapr_nvram_pre_load(void *opaque)
|
||||
|
||||
static void postload_update_cb(void *opaque, int running, RunState state)
|
||||
{
|
||||
sPAPRNVRAM *nvram = opaque;
|
||||
SpaprNvram *nvram = opaque;
|
||||
|
||||
/* This is called after bdrv_invalidate_cache_all. */
|
||||
|
||||
@ -225,7 +225,7 @@ static void postload_update_cb(void *opaque, int running, RunState state)
|
||||
|
||||
static int spapr_nvram_post_load(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
SpaprNvram *nvram = VIO_SPAPR_NVRAM(opaque);
|
||||
|
||||
if (nvram->blk) {
|
||||
nvram->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
|
||||
@ -242,22 +242,22 @@ static const VMStateDescription vmstate_spapr_nvram = {
|
||||
.pre_load = spapr_nvram_pre_load,
|
||||
.post_load = spapr_nvram_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(size, sPAPRNVRAM),
|
||||
VMSTATE_VBUFFER_ALLOC_UINT32(buf, sPAPRNVRAM, 1, NULL, size),
|
||||
VMSTATE_UINT32(size, SpaprNvram),
|
||||
VMSTATE_VBUFFER_ALLOC_UINT32(buf, SpaprNvram, 1, NULL, size),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static Property spapr_nvram_properties[] = {
|
||||
DEFINE_SPAPR_PROPERTIES(sPAPRNVRAM, sdev),
|
||||
DEFINE_PROP_DRIVE("drive", sPAPRNVRAM, blk),
|
||||
DEFINE_SPAPR_PROPERTIES(SpaprNvram, sdev),
|
||||
DEFINE_PROP_DRIVE("drive", SpaprNvram, blk),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void spapr_nvram_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = spapr_nvram_realize;
|
||||
k->devnode = spapr_nvram_devnode;
|
||||
@ -274,7 +274,7 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
|
||||
static const TypeInfo spapr_nvram_type_info = {
|
||||
.name = TYPE_VIO_SPAPR_NVRAM,
|
||||
.parent = TYPE_VIO_SPAPR_DEVICE,
|
||||
.instance_size = sizeof(sPAPRNVRAM),
|
||||
.instance_size = sizeof(SpaprNvram),
|
||||
.class_init = spapr_nvram_class_init,
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/net/fsl_etsec/etsec.h"
|
||||
#include "hw/i2c/i2c.h"
|
||||
|
||||
#define EPAPR_MAGIC (0x45504150)
|
||||
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
|
||||
@ -63,7 +64,10 @@
|
||||
#define MPC8544_PCI_REGS_SIZE 0x1000ULL
|
||||
#define MPC8544_UTIL_OFFSET 0xe0000ULL
|
||||
#define MPC8XXX_GPIO_OFFSET 0x000FF000ULL
|
||||
#define MPC8544_I2C_REGS_OFFSET 0x3000ULL
|
||||
#define MPC8XXX_GPIO_IRQ 47
|
||||
#define MPC8544_I2C_IRQ 43
|
||||
#define RTC_REGS_OFFSET 0x68
|
||||
|
||||
struct boot_info
|
||||
{
|
||||
@ -161,6 +165,39 @@ static void create_dt_mpc8xxx_gpio(void *fdt, const char *soc, const char *mpic)
|
||||
g_free(poweroff);
|
||||
}
|
||||
|
||||
static void dt_rtc_create(void *fdt, const char *i2c, const char *alias)
|
||||
{
|
||||
int offset = RTC_REGS_OFFSET;
|
||||
|
||||
gchar *rtc = g_strdup_printf("%s/rtc@%"PRIx32, i2c, offset);
|
||||
qemu_fdt_add_subnode(fdt, rtc);
|
||||
qemu_fdt_setprop_string(fdt, rtc, "compatible", "pericom,pt7c4338");
|
||||
qemu_fdt_setprop_cells(fdt, rtc, "reg", offset);
|
||||
qemu_fdt_setprop_string(fdt, "/aliases", alias, rtc);
|
||||
|
||||
g_free(rtc);
|
||||
}
|
||||
|
||||
static void dt_i2c_create(void *fdt, const char *soc, const char *mpic,
|
||||
const char *alias)
|
||||
{
|
||||
hwaddr mmio0 = MPC8544_I2C_REGS_OFFSET;
|
||||
int irq0 = MPC8544_I2C_IRQ;
|
||||
|
||||
gchar *i2c = g_strdup_printf("%s/i2c@%"PRIx64, soc, mmio0);
|
||||
qemu_fdt_add_subnode(fdt, i2c);
|
||||
qemu_fdt_setprop_string(fdt, i2c, "device_type", "i2c");
|
||||
qemu_fdt_setprop_string(fdt, i2c, "compatible", "fsl-i2c");
|
||||
qemu_fdt_setprop_cells(fdt, i2c, "reg", mmio0, 0x14);
|
||||
qemu_fdt_setprop_cells(fdt, i2c, "cell-index", 0);
|
||||
qemu_fdt_setprop_cells(fdt, i2c, "interrupts", irq0, 0x2);
|
||||
qemu_fdt_setprop_phandle(fdt, i2c, "interrupt-parent", mpic);
|
||||
qemu_fdt_setprop_string(fdt, "/aliases", alias, i2c);
|
||||
|
||||
g_free(i2c);
|
||||
}
|
||||
|
||||
|
||||
typedef struct PlatformDevtreeData {
|
||||
void *fdt;
|
||||
const char *mpic;
|
||||
@ -464,6 +501,12 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
|
||||
soc, mpic, "serial0", 0, true);
|
||||
}
|
||||
|
||||
/* i2c */
|
||||
dt_i2c_create(fdt, soc, mpic, "i2c");
|
||||
|
||||
dt_rtc_create(fdt, "i2c", "rtc");
|
||||
|
||||
|
||||
gutil = g_strdup_printf("%s/global-utilities@%llx", soc,
|
||||
MPC8544_UTIL_OFFSET);
|
||||
qemu_fdt_add_subnode(fdt, gutil);
|
||||
@ -812,6 +855,7 @@ void ppce500_init(MachineState *machine)
|
||||
MemoryRegion *ccsr_addr_space;
|
||||
SysBusDevice *s;
|
||||
PPCE500CCSRState *ccsr;
|
||||
I2CBus *i2c;
|
||||
|
||||
irqs = g_new0(IrqLines, smp_cpus);
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
@ -887,6 +931,16 @@ void ppce500_init(MachineState *machine)
|
||||
0, qdev_get_gpio_in(mpicdev, 42), 399193,
|
||||
serial_hd(1), DEVICE_BIG_ENDIAN);
|
||||
}
|
||||
/* I2C */
|
||||
dev = qdev_create(NULL, "mpc-i2c");
|
||||
s = SYS_BUS_DEVICE(dev);
|
||||
qdev_init_nofail(dev);
|
||||
sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC8544_I2C_IRQ));
|
||||
memory_region_add_subregion(ccsr_addr_space, MPC8544_I2C_REGS_OFFSET,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||
i2c_create_slave(i2c, "ds1338", RTC_REGS_OFFSET);
|
||||
|
||||
|
||||
/* General Utility device */
|
||||
dev = qdev_create(NULL, "mpc8544-guts");
|
||||
|
@ -547,11 +547,11 @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
|
||||
return g_strdup("cdrom");
|
||||
}
|
||||
|
||||
return g_strdup("hd");
|
||||
return g_strdup("disk");
|
||||
}
|
||||
|
||||
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
|
||||
return g_strdup("hd");
|
||||
return g_strdup("disk");
|
||||
}
|
||||
|
||||
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {
|
||||
|
@ -402,11 +402,11 @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
|
||||
return g_strdup("cdrom");
|
||||
}
|
||||
|
||||
return g_strdup("hd");
|
||||
return g_strdup("disk");
|
||||
}
|
||||
|
||||
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
|
||||
return g_strdup("hd");
|
||||
return g_strdup("disk");
|
||||
}
|
||||
|
||||
if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {
|
||||
|
252
hw/ppc/pnv.c
252
hw/ppc/pnv.c
@ -267,7 +267,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
|
||||
g_free(reg);
|
||||
}
|
||||
|
||||
static void pnv_dt_chip(PnvChip *chip, void *fdt)
|
||||
static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
|
||||
{
|
||||
const char *typename = pnv_chip_core_typename(chip);
|
||||
size_t typesize = object_type_get_instance_size(typename);
|
||||
@ -289,6 +289,27 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt)
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
|
||||
{
|
||||
const char *typename = pnv_chip_core_typename(chip);
|
||||
size_t typesize = object_type_get_instance_size(typename);
|
||||
int i;
|
||||
|
||||
pnv_dt_xscom(chip, fdt, 0);
|
||||
|
||||
for (i = 0; i < chip->nr_cores; i++) {
|
||||
PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
|
||||
|
||||
pnv_dt_core(chip, pnv_core, fdt);
|
||||
}
|
||||
|
||||
if (chip->ram_size) {
|
||||
pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
|
||||
}
|
||||
|
||||
pnv_dt_lpc(chip, fdt, 0);
|
||||
}
|
||||
|
||||
static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
|
||||
{
|
||||
uint32_t io_base = d->ioport_id;
|
||||
@ -398,24 +419,12 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pnv_chip_isa_offset(PnvChip *chip, void *fdt)
|
||||
{
|
||||
char *name;
|
||||
int offset;
|
||||
|
||||
name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
|
||||
(uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE);
|
||||
offset = fdt_path_offset(fdt, name);
|
||||
g_free(name);
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* The default LPC bus of a multichip system is on chip 0. It's
|
||||
* recognized by the firmware (skiboot) using a "primary" property.
|
||||
*/
|
||||
static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
|
||||
{
|
||||
int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt);
|
||||
int isa_offset = fdt_path_offset(fdt, pnv->chips[0]->dt_isa_nodename);
|
||||
ForeachPopulateArgs args = {
|
||||
.fdt = fdt,
|
||||
.offset = isa_offset,
|
||||
@ -429,6 +438,16 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
|
||||
&args);
|
||||
}
|
||||
|
||||
static void pnv_dt_power_mgt(void *fdt)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_add_subnode(fdt, 0, "ibm,opal");
|
||||
off = fdt_add_subnode(fdt, off, "power-mgt");
|
||||
|
||||
_FDT(fdt_setprop_cell(fdt, off, "ibm,enabled-stop-levels", 0xc0000000));
|
||||
}
|
||||
|
||||
static void *pnv_dt_create(MachineState *machine)
|
||||
{
|
||||
const char plat_compat[] = "qemu,powernv\0ibm,powernv";
|
||||
@ -474,7 +493,7 @@ static void *pnv_dt_create(MachineState *machine)
|
||||
|
||||
/* Populate device tree for each chip */
|
||||
for (i = 0; i < pnv->num_chips; i++) {
|
||||
pnv_dt_chip(pnv->chips[i], fdt);
|
||||
PNV_CHIP_GET_CLASS(pnv->chips[i])->dt_populate(pnv->chips[i], fdt);
|
||||
}
|
||||
|
||||
/* Populate ISA devices on chip 0 */
|
||||
@ -484,6 +503,11 @@ static void *pnv_dt_create(MachineState *machine)
|
||||
pnv_dt_bmc_sensors(pnv->bmc, fdt);
|
||||
}
|
||||
|
||||
/* Create an extra node for power management on Power9 */
|
||||
if (pnv_is_power9(pnv)) {
|
||||
pnv_dt_power_mgt(fdt);
|
||||
}
|
||||
|
||||
return fdt;
|
||||
}
|
||||
|
||||
@ -540,7 +564,8 @@ static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
|
||||
|
||||
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
|
||||
{
|
||||
return NULL;
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(chip);
|
||||
return pnv_lpc_isa_create(&chip9->lpc, false, errp);
|
||||
}
|
||||
|
||||
static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
|
||||
@ -548,6 +573,21 @@ static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
|
||||
return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp);
|
||||
}
|
||||
|
||||
static void pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon)
|
||||
{
|
||||
Pnv8Chip *chip8 = PNV8_CHIP(chip);
|
||||
|
||||
ics_pic_print_info(&chip8->psi.ics, mon);
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
|
||||
{
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(chip);
|
||||
|
||||
pnv_xive_pic_print_info(&chip9->xive, mon);
|
||||
pnv_psi_pic_print_info(&chip9->psi, mon);
|
||||
}
|
||||
|
||||
static void pnv_init(MachineState *machine)
|
||||
{
|
||||
PnvMachineState *pnv = PNV_MACHINE(machine);
|
||||
@ -684,7 +724,7 @@ static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
|
||||
return;
|
||||
}
|
||||
|
||||
pnv_cpu->icp = ICP(obj);
|
||||
pnv_cpu->intc = obj;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -705,7 +745,23 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
|
||||
static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
|
||||
Error **errp)
|
||||
{
|
||||
return;
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(chip);
|
||||
Error *local_err = NULL;
|
||||
Object *obj;
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
|
||||
/*
|
||||
* The core creates its interrupt presenter but the XIVE interrupt
|
||||
* controller object is initialized afterwards. Hopefully, it's
|
||||
* only used at runtime.
|
||||
*/
|
||||
obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(&chip9->xive), errp);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
pnv_cpu->intc = obj;
|
||||
}
|
||||
|
||||
/* Allowed core identifiers on a POWER8 Processor Chip :
|
||||
@ -739,17 +795,17 @@ static void pnv_chip_power8_instance_init(Object *obj)
|
||||
Pnv8Chip *chip8 = PNV8_CHIP(obj);
|
||||
|
||||
object_initialize_child(obj, "psi", &chip8->psi, sizeof(chip8->psi),
|
||||
TYPE_PNV_PSI, &error_abort, NULL);
|
||||
TYPE_PNV8_PSI, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip8->psi), "xics",
|
||||
OBJECT(qdev_get_machine()), &error_abort);
|
||||
|
||||
object_initialize_child(obj, "lpc", &chip8->lpc, sizeof(chip8->lpc),
|
||||
TYPE_PNV_LPC, &error_abort, NULL);
|
||||
TYPE_PNV8_LPC, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip8->lpc), "psi",
|
||||
OBJECT(&chip8->psi), &error_abort);
|
||||
|
||||
object_initialize_child(obj, "occ", &chip8->occ, sizeof(chip8->occ),
|
||||
TYPE_PNV_OCC, &error_abort, NULL);
|
||||
TYPE_PNV8_OCC, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip8->occ), "psi",
|
||||
OBJECT(&chip8->psi), &error_abort);
|
||||
}
|
||||
@ -791,6 +847,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
|
||||
PnvChip *chip = PNV_CHIP(dev);
|
||||
Pnv8Chip *chip8 = PNV8_CHIP(dev);
|
||||
Pnv8Psi *psi8 = &chip8->psi;
|
||||
Error *local_err = NULL;
|
||||
|
||||
pcc->parent_realize(dev, &local_err);
|
||||
@ -807,13 +864,18 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs);
|
||||
pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE,
|
||||
&PNV_PSI(psi8)->xscom_regs);
|
||||
|
||||
/* Create LPC controller */
|
||||
object_property_set_bool(OBJECT(&chip8->lpc), true, "realized",
|
||||
&error_fatal);
|
||||
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
|
||||
|
||||
chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
|
||||
(uint64_t) PNV_XSCOM_BASE(chip),
|
||||
PNV_XSCOM_LPC_BASE);
|
||||
|
||||
/* Interrupt Management Area. This is the memory region holding
|
||||
* all the Interrupt Control Presenter (ICP) registers */
|
||||
pnv_chip_icp_realize(chip8, &local_err);
|
||||
@ -842,6 +904,8 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->isa_create = pnv_chip_power8_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
k->xscom_base = 0x003fc0000000000ull;
|
||||
dc->desc = "PowerNV Chip POWER8E";
|
||||
|
||||
@ -860,6 +924,8 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->isa_create = pnv_chip_power8_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
k->xscom_base = 0x003fc0000000000ull;
|
||||
dc->desc = "PowerNV Chip POWER8";
|
||||
|
||||
@ -878,6 +944,8 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->isa_create = pnv_chip_power8nvl_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
k->xscom_base = 0x003fc0000000000ull;
|
||||
dc->desc = "PowerNV Chip POWER8NVL";
|
||||
|
||||
@ -887,11 +955,65 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
static void pnv_chip_power9_instance_init(Object *obj)
|
||||
{
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(obj);
|
||||
|
||||
object_initialize_child(obj, "xive", &chip9->xive, sizeof(chip9->xive),
|
||||
TYPE_PNV_XIVE, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip9->xive), "chip", obj,
|
||||
&error_abort);
|
||||
|
||||
object_initialize_child(obj, "psi", &chip9->psi, sizeof(chip9->psi),
|
||||
TYPE_PNV9_PSI, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip9->psi), "chip", obj,
|
||||
&error_abort);
|
||||
|
||||
object_initialize_child(obj, "lpc", &chip9->lpc, sizeof(chip9->lpc),
|
||||
TYPE_PNV9_LPC, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip9->lpc), "psi",
|
||||
OBJECT(&chip9->psi), &error_abort);
|
||||
|
||||
object_initialize_child(obj, "occ", &chip9->occ, sizeof(chip9->occ),
|
||||
TYPE_PNV9_OCC, &error_abort, NULL);
|
||||
object_property_add_const_link(OBJECT(&chip9->occ), "psi",
|
||||
OBJECT(&chip9->psi), &error_abort);
|
||||
}
|
||||
|
||||
static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp)
|
||||
{
|
||||
PnvChip *chip = PNV_CHIP(chip9);
|
||||
const char *typename = pnv_chip_core_typename(chip);
|
||||
size_t typesize = object_type_get_instance_size(typename);
|
||||
int i;
|
||||
|
||||
chip9->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
|
||||
chip9->quads = g_new0(PnvQuad, chip9->nr_quads);
|
||||
|
||||
for (i = 0; i < chip9->nr_quads; i++) {
|
||||
char eq_name[32];
|
||||
PnvQuad *eq = &chip9->quads[i];
|
||||
PnvCore *pnv_core = PNV_CORE(chip->cores + (i * 4) * typesize);
|
||||
int core_id = CPU_CORE(pnv_core)->core_id;
|
||||
|
||||
object_initialize(eq, sizeof(*eq), TYPE_PNV_QUAD);
|
||||
snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
|
||||
|
||||
object_property_add_child(OBJECT(chip), eq_name, OBJECT(eq),
|
||||
&error_fatal);
|
||||
object_property_set_int(OBJECT(eq), core_id, "id", &error_fatal);
|
||||
object_property_set_bool(OBJECT(eq), true, "realized", &error_fatal);
|
||||
object_unref(OBJECT(eq));
|
||||
|
||||
pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->id),
|
||||
&eq->xscom_regs);
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(dev);
|
||||
PnvChip *chip = PNV_CHIP(dev);
|
||||
Pnv9Psi *psi9 = &chip9->psi;
|
||||
Error *local_err = NULL;
|
||||
|
||||
pcc->parent_realize(dev, &local_err);
|
||||
@ -899,6 +1021,61 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
pnv_chip_quad_realize(chip9, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* XIVE interrupt controller (POWER9) */
|
||||
object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_IC_BASE(chip),
|
||||
"ic-bar", &error_fatal);
|
||||
object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_VC_BASE(chip),
|
||||
"vc-bar", &error_fatal);
|
||||
object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_PC_BASE(chip),
|
||||
"pc-bar", &error_fatal);
|
||||
object_property_set_int(OBJECT(&chip9->xive), PNV9_XIVE_TM_BASE(chip),
|
||||
"tm-bar", &error_fatal);
|
||||
object_property_set_bool(OBJECT(&chip9->xive), true, "realized",
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
pnv_xscom_add_subregion(chip, PNV9_XSCOM_XIVE_BASE,
|
||||
&chip9->xive.xscom_regs);
|
||||
|
||||
/* Processor Service Interface (PSI) Host Bridge */
|
||||
object_property_set_int(OBJECT(&chip9->psi), PNV9_PSIHB_BASE(chip),
|
||||
"bar", &error_fatal);
|
||||
object_property_set_bool(OBJECT(&chip9->psi), true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
pnv_xscom_add_subregion(chip, PNV9_XSCOM_PSIHB_BASE,
|
||||
&PNV_PSI(psi9)->xscom_regs);
|
||||
|
||||
/* LPC */
|
||||
object_property_set_bool(OBJECT(&chip9->lpc), true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
|
||||
&chip9->lpc.xscom_regs);
|
||||
|
||||
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
|
||||
(uint64_t) PNV9_LPCM_BASE(chip));
|
||||
|
||||
/* Create the simplified OCC model */
|
||||
object_property_set_bool(OBJECT(&chip9->occ), true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
|
||||
@ -912,6 +1089,8 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_pir_p9;
|
||||
k->intc_create = pnv_chip_power9_intc_create;
|
||||
k->isa_create = pnv_chip_power9_isa_create;
|
||||
k->dt_populate = pnv_chip_power9_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power9_pic_print_info;
|
||||
k->xscom_base = 0x00603fc00000000ull;
|
||||
dc->desc = "PowerNV Chip POWER9";
|
||||
|
||||
@ -1007,7 +1186,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
|
||||
if (!pnv_chip_is_power9(chip)) {
|
||||
xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
|
||||
} else {
|
||||
xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
|
||||
xscom_core_base = PNV9_XSCOM_EC_BASE(core_hwid);
|
||||
}
|
||||
|
||||
pnv_xscom_add_subregion(chip, xscom_core_base,
|
||||
@ -1082,27 +1261,11 @@ static void pnv_ics_resend(XICSFabric *xi)
|
||||
}
|
||||
}
|
||||
|
||||
static PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
CPU_FOREACH(cs) {
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
if (env->spr_cb[SPR_PIR].default_value == pir) {
|
||||
return cpu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
|
||||
|
||||
return cpu ? pnv_cpu_state(cpu)->icp : NULL;
|
||||
return cpu ? ICP(pnv_cpu_state(cpu)->intc) : NULL;
|
||||
}
|
||||
|
||||
static void pnv_pic_print_info(InterruptStatsProvider *obj,
|
||||
@ -1115,12 +1278,15 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
|
||||
CPU_FOREACH(cs) {
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
|
||||
icp_pic_print_info(pnv_cpu_state(cpu)->icp, mon);
|
||||
if (pnv_chip_is_power9(pnv->chips[0])) {
|
||||
xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), mon);
|
||||
} else {
|
||||
icp_pic_print_info(ICP(pnv_cpu_state(cpu)->intc), mon);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pnv->num_chips; i++) {
|
||||
Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]);
|
||||
ics_pic_print_info(&chip8->psi.ics, mon);
|
||||
PNV_CHIP_GET_CLASS(pnv->chips[i])->pic_print_info(pnv->chips[i], mon);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,8 +60,8 @@ static void pnv_cpu_reset(void *opaque)
|
||||
#define PNV_XSCOM_EX_DTS_RESULT0 0x50000
|
||||
#define PNV_XSCOM_EX_DTS_RESULT1 0x50001
|
||||
|
||||
static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned int width)
|
||||
static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned int width)
|
||||
{
|
||||
uint32_t offset = addr >> 3;
|
||||
uint64_t val = 0;
|
||||
@ -82,16 +82,74 @@ static uint64_t pnv_core_xscom_read(void *opaque, hwaddr addr,
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_core_xscom_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned int width)
|
||||
static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned int width)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
|
||||
addr);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_core_xscom_ops = {
|
||||
.read = pnv_core_xscom_read,
|
||||
.write = pnv_core_xscom_write,
|
||||
static const MemoryRegionOps pnv_core_power8_xscom_ops = {
|
||||
.read = pnv_core_power8_xscom_read,
|
||||
.write = pnv_core_power8_xscom_write,
|
||||
.valid.min_access_size = 8,
|
||||
.valid.max_access_size = 8,
|
||||
.impl.min_access_size = 8,
|
||||
.impl.max_access_size = 8,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* POWER9 core controls
|
||||
*/
|
||||
#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d
|
||||
#define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a
|
||||
|
||||
static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned int width)
|
||||
{
|
||||
uint32_t offset = addr >> 3;
|
||||
uint64_t val = 0;
|
||||
|
||||
/* The result should be 38 C */
|
||||
switch (offset) {
|
||||
case PNV_XSCOM_EX_DTS_RESULT0:
|
||||
val = 0x26f024f023f0000ull;
|
||||
break;
|
||||
case PNV_XSCOM_EX_DTS_RESULT1:
|
||||
val = 0x24f000000000000ull;
|
||||
break;
|
||||
case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
|
||||
case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
|
||||
val = 0x0;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n",
|
||||
addr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned int width)
|
||||
{
|
||||
uint32_t offset = addr >> 3;
|
||||
|
||||
switch (offset) {
|
||||
case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP:
|
||||
case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR:
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n",
|
||||
addr);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_core_power9_xscom_ops = {
|
||||
.read = pnv_core_power9_xscom_read,
|
||||
.write = pnv_core_power9_xscom_write,
|
||||
.valid.min_access_size = 8,
|
||||
.valid.max_access_size = 8,
|
||||
.impl.min_access_size = 8,
|
||||
@ -138,6 +196,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
|
||||
static void pnv_core_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvCore *pc = PNV_CORE(OBJECT(dev));
|
||||
PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
|
||||
CPUCore *cc = CPU_CORE(OBJECT(dev));
|
||||
const char *typename = pnv_core_cpu_typename(pc);
|
||||
Error *local_err = NULL;
|
||||
@ -180,7 +239,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
|
||||
pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
|
||||
pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
|
||||
pc, name, PNV_XSCOM_EX_SIZE);
|
||||
return;
|
||||
|
||||
@ -198,7 +257,7 @@ static void pnv_unrealize_vcpu(PowerPCCPU *cpu)
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
|
||||
qemu_unregister_reset(pnv_cpu_reset, cpu);
|
||||
object_unparent(OBJECT(pnv_cpu_state(cpu)->icp));
|
||||
object_unparent(OBJECT(pnv_cpu_state(cpu)->intc));
|
||||
cpu_remove_sync(CPU(cpu));
|
||||
cpu->machine_data = NULL;
|
||||
g_free(pnv_cpu);
|
||||
@ -222,6 +281,20 @@ static Property pnv_core_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void pnv_core_power8_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
|
||||
|
||||
pcc->xscom_ops = &pnv_core_power8_xscom_ops;
|
||||
}
|
||||
|
||||
static void pnv_core_power9_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
PnvCoreClass *pcc = PNV_CORE_CLASS(oc);
|
||||
|
||||
pcc->xscom_ops = &pnv_core_power9_xscom_ops;
|
||||
}
|
||||
|
||||
static void pnv_core_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
@ -231,10 +304,11 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
|
||||
dc->props = pnv_core_properties;
|
||||
}
|
||||
|
||||
#define DEFINE_PNV_CORE_TYPE(cpu_model) \
|
||||
#define DEFINE_PNV_CORE_TYPE(family, cpu_model) \
|
||||
{ \
|
||||
.parent = TYPE_PNV_CORE, \
|
||||
.name = PNV_CORE_TYPE_NAME(cpu_model), \
|
||||
.class_init = pnv_core_##family##_class_init, \
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_core_infos[] = {
|
||||
@ -246,10 +320,97 @@ static const TypeInfo pnv_core_infos[] = {
|
||||
.class_init = pnv_core_class_init,
|
||||
.abstract = true,
|
||||
},
|
||||
DEFINE_PNV_CORE_TYPE("power8e_v2.1"),
|
||||
DEFINE_PNV_CORE_TYPE("power8_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE("power8nvl_v1.0"),
|
||||
DEFINE_PNV_CORE_TYPE("power9_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
|
||||
};
|
||||
|
||||
DEFINE_TYPES(pnv_core_infos)
|
||||
|
||||
/*
|
||||
* POWER9 Quads
|
||||
*/
|
||||
|
||||
#define P9X_EX_NCU_SPEC_BAR 0x11010
|
||||
|
||||
static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned int width)
|
||||
{
|
||||
uint32_t offset = addr >> 3;
|
||||
uint64_t val = -1;
|
||||
|
||||
switch (offset) {
|
||||
case P9X_EX_NCU_SPEC_BAR:
|
||||
case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
|
||||
val = 0;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
|
||||
offset);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned int width)
|
||||
{
|
||||
uint32_t offset = addr >> 3;
|
||||
|
||||
switch (offset) {
|
||||
case P9X_EX_NCU_SPEC_BAR:
|
||||
case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_quad_xscom_ops = {
|
||||
.read = pnv_quad_xscom_read,
|
||||
.write = pnv_quad_xscom_write,
|
||||
.valid.min_access_size = 8,
|
||||
.valid.max_access_size = 8,
|
||||
.impl.min_access_size = 8,
|
||||
.impl.max_access_size = 8,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static void pnv_quad_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvQuad *eq = PNV_QUAD(dev);
|
||||
char name[32];
|
||||
|
||||
snprintf(name, sizeof(name), "xscom-quad.%d", eq->id);
|
||||
pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops,
|
||||
eq, name, PNV9_XSCOM_EQ_SIZE);
|
||||
}
|
||||
|
||||
static Property pnv_quad_properties[] = {
|
||||
DEFINE_PROP_UINT32("id", PnvQuad, id, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void pnv_quad_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
|
||||
dc->realize = pnv_quad_realize;
|
||||
dc->props = pnv_quad_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_quad_info = {
|
||||
.name = TYPE_PNV_QUAD,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(PnvQuad),
|
||||
.class_init = pnv_quad_class_init,
|
||||
};
|
||||
|
||||
static void pnv_core_register_types(void)
|
||||
{
|
||||
type_register_static(&pnv_quad_info);
|
||||
}
|
||||
|
||||
type_init(pnv_core_register_types)
|
||||
|
316
hw/ppc/pnv_lpc.c
316
hw/ppc/pnv_lpc.c
@ -39,6 +39,8 @@ enum {
|
||||
};
|
||||
|
||||
/* OPB Master LS registers */
|
||||
#define OPB_MASTER_LS_ROUTE0 0x8
|
||||
#define OPB_MASTER_LS_ROUTE1 0xC
|
||||
#define OPB_MASTER_LS_IRQ_STAT 0x50
|
||||
#define OPB_MASTER_IRQ_LPC 0x00000800
|
||||
#define OPB_MASTER_LS_IRQ_MASK 0x54
|
||||
@ -89,10 +91,11 @@ enum {
|
||||
#define LPC_FW_OPB_SIZE 0x10000000
|
||||
|
||||
#define LPC_OPB_REGS_OPB_ADDR 0xc0010000
|
||||
#define LPC_OPB_REGS_OPB_SIZE 0x00002000
|
||||
#define LPC_OPB_REGS_OPB_SIZE 0x00000060
|
||||
#define LPC_OPB_REGS_OPBA_ADDR 0xc0011000
|
||||
#define LPC_OPB_REGS_OPBA_SIZE 0x00000008
|
||||
#define LPC_HC_REGS_OPB_ADDR 0xc0012000
|
||||
#define LPC_HC_REGS_OPB_SIZE 0x00001000
|
||||
|
||||
#define LPC_HC_REGS_OPB_SIZE 0x00000100
|
||||
|
||||
static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
|
||||
{
|
||||
@ -117,6 +120,100 @@ static int pnv_lpc_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* POWER9 only */
|
||||
int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset)
|
||||
{
|
||||
const char compat[] = "ibm,power9-lpcm-opb\0simple-bus";
|
||||
const char lpc_compat[] = "ibm,power9-lpc\0ibm,lpc";
|
||||
char *name;
|
||||
int offset, lpcm_offset;
|
||||
uint64_t lpcm_addr = PNV9_LPCM_BASE(chip);
|
||||
uint32_t opb_ranges[8] = { 0,
|
||||
cpu_to_be32(lpcm_addr >> 32),
|
||||
cpu_to_be32((uint32_t)lpcm_addr),
|
||||
cpu_to_be32(PNV9_LPCM_SIZE / 2),
|
||||
cpu_to_be32(PNV9_LPCM_SIZE / 2),
|
||||
cpu_to_be32(lpcm_addr >> 32),
|
||||
cpu_to_be32(PNV9_LPCM_SIZE / 2),
|
||||
cpu_to_be32(PNV9_LPCM_SIZE / 2),
|
||||
};
|
||||
uint32_t opb_reg[4] = { cpu_to_be32(lpcm_addr >> 32),
|
||||
cpu_to_be32((uint32_t)lpcm_addr),
|
||||
cpu_to_be32(PNV9_LPCM_SIZE >> 32),
|
||||
cpu_to_be32((uint32_t)PNV9_LPCM_SIZE),
|
||||
};
|
||||
uint32_t reg[2];
|
||||
|
||||
/*
|
||||
* OPB bus
|
||||
*/
|
||||
name = g_strdup_printf("lpcm-opb@%"PRIx64, lpcm_addr);
|
||||
lpcm_offset = fdt_add_subnode(fdt, root_offset, name);
|
||||
_FDT(lpcm_offset);
|
||||
g_free(name);
|
||||
|
||||
_FDT((fdt_setprop(fdt, lpcm_offset, "reg", opb_reg, sizeof(opb_reg))));
|
||||
_FDT((fdt_setprop_cell(fdt, lpcm_offset, "#address-cells", 1)));
|
||||
_FDT((fdt_setprop_cell(fdt, lpcm_offset, "#size-cells", 1)));
|
||||
_FDT((fdt_setprop(fdt, lpcm_offset, "compatible", compat, sizeof(compat))));
|
||||
_FDT((fdt_setprop_cell(fdt, lpcm_offset, "ibm,chip-id", chip->chip_id)));
|
||||
_FDT((fdt_setprop(fdt, lpcm_offset, "ranges", opb_ranges,
|
||||
sizeof(opb_ranges))));
|
||||
|
||||
/*
|
||||
* OPB Master registers
|
||||
*/
|
||||
name = g_strdup_printf("opb-master@%x", LPC_OPB_REGS_OPB_ADDR);
|
||||
offset = fdt_add_subnode(fdt, lpcm_offset, name);
|
||||
_FDT(offset);
|
||||
g_free(name);
|
||||
|
||||
reg[0] = cpu_to_be32(LPC_OPB_REGS_OPB_ADDR);
|
||||
reg[1] = cpu_to_be32(LPC_OPB_REGS_OPB_SIZE);
|
||||
_FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
|
||||
_FDT((fdt_setprop_string(fdt, offset, "compatible",
|
||||
"ibm,power9-lpcm-opb-master")));
|
||||
|
||||
/*
|
||||
* OPB arbitrer registers
|
||||
*/
|
||||
name = g_strdup_printf("opb-arbitrer@%x", LPC_OPB_REGS_OPBA_ADDR);
|
||||
offset = fdt_add_subnode(fdt, lpcm_offset, name);
|
||||
_FDT(offset);
|
||||
g_free(name);
|
||||
|
||||
reg[0] = cpu_to_be32(LPC_OPB_REGS_OPBA_ADDR);
|
||||
reg[1] = cpu_to_be32(LPC_OPB_REGS_OPBA_SIZE);
|
||||
_FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
|
||||
_FDT((fdt_setprop_string(fdt, offset, "compatible",
|
||||
"ibm,power9-lpcm-opb-arbiter")));
|
||||
|
||||
/*
|
||||
* LPC Host Controller registers
|
||||
*/
|
||||
name = g_strdup_printf("lpc-controller@%x", LPC_HC_REGS_OPB_ADDR);
|
||||
offset = fdt_add_subnode(fdt, lpcm_offset, name);
|
||||
_FDT(offset);
|
||||
g_free(name);
|
||||
|
||||
reg[0] = cpu_to_be32(LPC_HC_REGS_OPB_ADDR);
|
||||
reg[1] = cpu_to_be32(LPC_HC_REGS_OPB_SIZE);
|
||||
_FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
|
||||
_FDT((fdt_setprop_string(fdt, offset, "compatible",
|
||||
"ibm,power9-lpc-controller")));
|
||||
|
||||
name = g_strdup_printf("lpc@0");
|
||||
offset = fdt_add_subnode(fdt, lpcm_offset, name);
|
||||
_FDT(offset);
|
||||
g_free(name);
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
|
||||
_FDT((fdt_setprop(fdt, offset, "compatible", lpc_compat,
|
||||
sizeof(lpc_compat))));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These read/write handlers of the OPB address space should be common
|
||||
* with the P9 LPC Controller which uses direct MMIOs.
|
||||
@ -241,9 +338,78 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = {
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
PnvLpcController *lpc = PNV_LPC(opaque);
|
||||
uint64_t val = 0;
|
||||
uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
|
||||
MemTxResult result;
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
val = address_space_ldl(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
|
||||
&result);
|
||||
break;
|
||||
case 1:
|
||||
val = address_space_ldub(&lpc->opb_as, opb_addr, MEMTXATTRS_UNSPECIFIED,
|
||||
&result);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
|
||||
HWADDR_PRIx " invalid size %d\n", addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_lpc_mmio_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PnvLpcController *lpc = PNV_LPC(opaque);
|
||||
uint32_t opb_addr = addr & ECCB_CTL_ADDR_MASK;
|
||||
MemTxResult result;
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
address_space_stl(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
|
||||
&result);
|
||||
break;
|
||||
case 1:
|
||||
address_space_stb(&lpc->opb_as, opb_addr, val, MEMTXATTRS_UNSPECIFIED,
|
||||
&result);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
|
||||
HWADDR_PRIx " invalid size %d\n", addr, size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_lpc_mmio_ops = {
|
||||
.read = pnv_lpc_mmio_read,
|
||||
.write = pnv_lpc_mmio_write,
|
||||
.impl = {
|
||||
.min_access_size = 1,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
|
||||
{
|
||||
bool lpc_to_opb_irq = false;
|
||||
PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
|
||||
|
||||
/* Update LPC controller to OPB line */
|
||||
if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
|
||||
@ -266,7 +432,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
|
||||
lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
|
||||
|
||||
/* Reflect the interrupt */
|
||||
pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_LPC_I2C, lpc->opb_irq_stat != 0);
|
||||
pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
|
||||
}
|
||||
|
||||
static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
|
||||
@ -294,7 +460,7 @@ static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
|
||||
val = lpc->lpc_hc_error_addr;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: Ox%"
|
||||
qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: 0x%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
}
|
||||
return val;
|
||||
@ -332,7 +498,7 @@ static void lpc_hc_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
case LPC_HC_ERROR_ADDRESS:
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: Ox%"
|
||||
qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented register: 0x%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
}
|
||||
}
|
||||
@ -357,6 +523,12 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
|
||||
uint64_t val = 0xfffffffffffffffful;
|
||||
|
||||
switch (addr) {
|
||||
case OPB_MASTER_LS_ROUTE0: /* TODO */
|
||||
val = lpc->opb_irq_route0;
|
||||
break;
|
||||
case OPB_MASTER_LS_ROUTE1: /* TODO */
|
||||
val = lpc->opb_irq_route1;
|
||||
break;
|
||||
case OPB_MASTER_LS_IRQ_STAT:
|
||||
val = lpc->opb_irq_stat;
|
||||
break;
|
||||
@ -370,7 +542,7 @@ static uint64_t opb_master_read(void *opaque, hwaddr addr, unsigned size)
|
||||
val = lpc->opb_irq_input;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OPB MASTER Unimplemented register: Ox%"
|
||||
qemu_log_mask(LOG_UNIMP, "OPBM: read on unimplemented register: 0x%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
}
|
||||
|
||||
@ -383,6 +555,12 @@ static void opb_master_write(void *opaque, hwaddr addr,
|
||||
PnvLpcController *lpc = opaque;
|
||||
|
||||
switch (addr) {
|
||||
case OPB_MASTER_LS_ROUTE0: /* TODO */
|
||||
lpc->opb_irq_route0 = val;
|
||||
break;
|
||||
case OPB_MASTER_LS_ROUTE1: /* TODO */
|
||||
lpc->opb_irq_route1 = val;
|
||||
break;
|
||||
case OPB_MASTER_LS_IRQ_STAT:
|
||||
lpc->opb_irq_stat &= ~val;
|
||||
pnv_lpc_eval_irqs(lpc);
|
||||
@ -399,8 +577,8 @@ static void opb_master_write(void *opaque, hwaddr addr,
|
||||
/* Read only */
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OPB MASTER Unimplemented register: Ox%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
qemu_log_mask(LOG_UNIMP, "OPBM: write on unimplemented register: 0x%"
|
||||
HWADDR_PRIx " val=0x%08"PRIx64"\n", addr, val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,11 +596,102 @@ static const MemoryRegionOps opb_master_ops = {
|
||||
},
|
||||
};
|
||||
|
||||
static void pnv_lpc_power8_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvLpcController *lpc = PNV_LPC(dev);
|
||||
PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
plc->parent_realize(dev, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* P8 uses a XSCOM region for LPC registers */
|
||||
pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(lpc),
|
||||
&pnv_lpc_xscom_ops, lpc, "xscom-lpc",
|
||||
PNV_XSCOM_LPC_SIZE);
|
||||
}
|
||||
|
||||
static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
|
||||
PnvLpcClass *plc = PNV_LPC_CLASS(klass);
|
||||
|
||||
dc->desc = "PowerNV LPC Controller POWER8";
|
||||
|
||||
xdc->dt_xscom = pnv_lpc_dt_xscom;
|
||||
|
||||
plc->psi_irq = PSIHB_IRQ_LPC_I2C;
|
||||
|
||||
device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
|
||||
&plc->parent_realize);
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_lpc_power8_info = {
|
||||
.name = TYPE_PNV8_LPC,
|
||||
.parent = TYPE_PNV_LPC,
|
||||
.instance_size = sizeof(PnvLpcController),
|
||||
.class_init = pnv_lpc_power8_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_PNV_XSCOM_INTERFACE },
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
static void pnv_lpc_power9_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvLpcController *lpc = PNV_LPC(dev);
|
||||
PnvLpcClass *plc = PNV_LPC_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
plc->parent_realize(dev, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* P9 uses a MMIO region */
|
||||
memory_region_init_io(&lpc->xscom_regs, OBJECT(lpc), &pnv_lpc_mmio_ops,
|
||||
lpc, "lpcm", PNV9_LPCM_SIZE);
|
||||
}
|
||||
|
||||
static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvLpcClass *plc = PNV_LPC_CLASS(klass);
|
||||
|
||||
dc->desc = "PowerNV LPC Controller POWER9";
|
||||
|
||||
plc->psi_irq = PSIHB9_IRQ_LPCHC;
|
||||
|
||||
device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
|
||||
&plc->parent_realize);
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_lpc_power9_info = {
|
||||
.name = TYPE_PNV9_LPC,
|
||||
.parent = TYPE_PNV_LPC,
|
||||
.instance_size = sizeof(PnvLpcController),
|
||||
.class_init = pnv_lpc_power9_class_init,
|
||||
};
|
||||
|
||||
static void pnv_lpc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvLpcController *lpc = PNV_LPC(dev);
|
||||
Object *obj;
|
||||
Error *error = NULL;
|
||||
Error *local_err = NULL;
|
||||
|
||||
obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
|
||||
if (!obj) {
|
||||
error_propagate(errp, local_err);
|
||||
error_prepend(errp, "required link 'psi' not found: ");
|
||||
return;
|
||||
}
|
||||
/* The LPC controller needs PSI to generate interrupts */
|
||||
lpc->psi = PNV_PSI(obj);
|
||||
|
||||
/* Reg inits */
|
||||
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
|
||||
@ -462,46 +731,29 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
|
||||
"lpc-hc", LPC_HC_REGS_OPB_SIZE);
|
||||
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
|
||||
&lpc->lpc_hc_regs);
|
||||
|
||||
/* XScom region for LPC registers */
|
||||
pnv_xscom_region_init(&lpc->xscom_regs, OBJECT(dev),
|
||||
&pnv_lpc_xscom_ops, lpc, "xscom-lpc",
|
||||
PNV_XSCOM_LPC_SIZE);
|
||||
|
||||
/* get PSI object from chip */
|
||||
obj = object_property_get_link(OBJECT(dev), "psi", &error);
|
||||
if (!obj) {
|
||||
error_setg(errp, "%s: required link 'psi' not found: %s",
|
||||
__func__, error_get_pretty(error));
|
||||
return;
|
||||
}
|
||||
lpc->psi = PNV_PSI(obj);
|
||||
}
|
||||
|
||||
static void pnv_lpc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
|
||||
|
||||
xdc->dt_xscom = pnv_lpc_dt_xscom;
|
||||
|
||||
dc->realize = pnv_lpc_realize;
|
||||
dc->desc = "PowerNV LPC Controller";
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_lpc_info = {
|
||||
.name = TYPE_PNV_LPC,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(PnvLpcController),
|
||||
.class_init = pnv_lpc_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_PNV_XSCOM_INTERFACE },
|
||||
{ }
|
||||
}
|
||||
.class_size = sizeof(PnvLpcClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void pnv_lpc_register_types(void)
|
||||
{
|
||||
type_register_static(&pnv_lpc_info);
|
||||
type_register_static(&pnv_lpc_power8_info);
|
||||
type_register_static(&pnv_lpc_power9_info);
|
||||
}
|
||||
|
||||
type_init(pnv_lpc_register_types)
|
||||
|
127
hw/ppc/pnv_occ.c
127
hw/ppc/pnv_occ.c
@ -34,15 +34,17 @@
|
||||
static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
|
||||
{
|
||||
bool irq_state;
|
||||
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
|
||||
|
||||
val &= 0xffff000000000000ull;
|
||||
|
||||
occ->occmisc = val;
|
||||
irq_state = !!(val >> 63);
|
||||
pnv_psi_irq_set(occ->psi, PSIHB_IRQ_OCC, irq_state);
|
||||
pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
|
||||
}
|
||||
|
||||
static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
|
||||
static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
PnvOCC *occ = PNV_OCC(opaque);
|
||||
uint32_t offset = addr >> 3;
|
||||
@ -54,13 +56,13 @@ static uint64_t pnv_occ_xscom_read(void *opaque, hwaddr addr, unsigned size)
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
HWADDR_PRIx "\n", addr >> 3);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
static void pnv_occ_power8_xscom_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PnvOCC *occ = PNV_OCC(opaque);
|
||||
uint32_t offset = addr >> 3;
|
||||
@ -77,13 +79,13 @@ static void pnv_occ_xscom_write(void *opaque, hwaddr addr,
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
|
||||
HWADDR_PRIx "\n", addr);
|
||||
HWADDR_PRIx "\n", addr >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_occ_xscom_ops = {
|
||||
.read = pnv_occ_xscom_read,
|
||||
.write = pnv_occ_xscom_write,
|
||||
static const MemoryRegionOps pnv_occ_power8_xscom_ops = {
|
||||
.read = pnv_occ_power8_xscom_read,
|
||||
.write = pnv_occ_power8_xscom_write,
|
||||
.valid.min_access_size = 8,
|
||||
.valid.max_access_size = 8,
|
||||
.impl.min_access_size = 8,
|
||||
@ -91,27 +93,113 @@ static const MemoryRegionOps pnv_occ_xscom_ops = {
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PnvOCCClass *poc = PNV_OCC_CLASS(klass);
|
||||
|
||||
poc->xscom_size = PNV_XSCOM_OCC_SIZE;
|
||||
poc->xscom_ops = &pnv_occ_power8_xscom_ops;
|
||||
poc->psi_irq = PSIHB_IRQ_OCC;
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_occ_power8_type_info = {
|
||||
.name = TYPE_PNV8_OCC,
|
||||
.parent = TYPE_PNV_OCC,
|
||||
.instance_size = sizeof(PnvOCC),
|
||||
.class_init = pnv_occ_power8_class_init,
|
||||
};
|
||||
|
||||
#define P9_OCB_OCI_OCCMISC 0x6080
|
||||
#define P9_OCB_OCI_OCCMISC_CLEAR 0x6081
|
||||
#define P9_OCB_OCI_OCCMISC_OR 0x6082
|
||||
|
||||
|
||||
static uint64_t pnv_occ_power9_xscom_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
PnvOCC *occ = PNV_OCC(opaque);
|
||||
uint32_t offset = addr >> 3;
|
||||
uint64_t val = 0;
|
||||
|
||||
switch (offset) {
|
||||
case P9_OCB_OCI_OCCMISC:
|
||||
val = occ->occmisc;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
|
||||
HWADDR_PRIx "\n", addr >> 3);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_occ_power9_xscom_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PnvOCC *occ = PNV_OCC(opaque);
|
||||
uint32_t offset = addr >> 3;
|
||||
|
||||
switch (offset) {
|
||||
case P9_OCB_OCI_OCCMISC_CLEAR:
|
||||
pnv_occ_set_misc(occ, 0);
|
||||
break;
|
||||
case P9_OCB_OCI_OCCMISC_OR:
|
||||
pnv_occ_set_misc(occ, occ->occmisc | val);
|
||||
break;
|
||||
case P9_OCB_OCI_OCCMISC:
|
||||
pnv_occ_set_misc(occ, val);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "OCC Unimplemented register: Ox%"
|
||||
HWADDR_PRIx "\n", addr >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_occ_power9_xscom_ops = {
|
||||
.read = pnv_occ_power9_xscom_read,
|
||||
.write = pnv_occ_power9_xscom_write,
|
||||
.valid.min_access_size = 8,
|
||||
.valid.max_access_size = 8,
|
||||
.impl.min_access_size = 8,
|
||||
.impl.max_access_size = 8,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PnvOCCClass *poc = PNV_OCC_CLASS(klass);
|
||||
|
||||
poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
|
||||
poc->xscom_ops = &pnv_occ_power9_xscom_ops;
|
||||
poc->psi_irq = PSIHB9_IRQ_OCC;
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_occ_power9_type_info = {
|
||||
.name = TYPE_PNV9_OCC,
|
||||
.parent = TYPE_PNV_OCC,
|
||||
.instance_size = sizeof(PnvOCC),
|
||||
.class_init = pnv_occ_power9_class_init,
|
||||
};
|
||||
|
||||
static void pnv_occ_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvOCC *occ = PNV_OCC(dev);
|
||||
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
|
||||
Object *obj;
|
||||
Error *error = NULL;
|
||||
Error *local_err = NULL;
|
||||
|
||||
occ->occmisc = 0;
|
||||
|
||||
/* get PSI object from chip */
|
||||
obj = object_property_get_link(OBJECT(dev), "psi", &error);
|
||||
obj = object_property_get_link(OBJECT(dev), "psi", &local_err);
|
||||
if (!obj) {
|
||||
error_setg(errp, "%s: required link 'psi' not found: %s",
|
||||
__func__, error_get_pretty(error));
|
||||
error_propagate(errp, local_err);
|
||||
error_prepend(errp, "required link 'psi' not found: ");
|
||||
return;
|
||||
}
|
||||
occ->psi = PNV_PSI(obj);
|
||||
|
||||
/* XScom region for OCC registers */
|
||||
pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), &pnv_occ_xscom_ops,
|
||||
occ, "xscom-occ", PNV_XSCOM_OCC_SIZE);
|
||||
pnv_xscom_region_init(&occ->xscom_regs, OBJECT(dev), poc->xscom_ops,
|
||||
occ, "xscom-occ", poc->xscom_size);
|
||||
}
|
||||
|
||||
static void pnv_occ_class_init(ObjectClass *klass, void *data)
|
||||
@ -119,6 +207,7 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->realize = pnv_occ_realize;
|
||||
dc->desc = "PowerNV OCC Controller";
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_occ_type_info = {
|
||||
@ -126,11 +215,15 @@ static const TypeInfo pnv_occ_type_info = {
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(PnvOCC),
|
||||
.class_init = pnv_occ_class_init,
|
||||
.class_size = sizeof(PnvOCCClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void pnv_occ_register_types(void)
|
||||
{
|
||||
type_register_static(&pnv_occ_type_info);
|
||||
type_register_static(&pnv_occ_power8_type_info);
|
||||
type_register_static(&pnv_occ_power9_type_info);
|
||||
}
|
||||
|
||||
type_init(pnv_occ_register_types)
|
||||
type_init(pnv_occ_register_types);
|
||||
|
425
hw/ppc/pnv_psi.c
425
hw/ppc/pnv_psi.c
@ -22,6 +22,7 @@
|
||||
#include "target/ppc/cpu.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qapi/error.h"
|
||||
#include "monitor/monitor.h"
|
||||
|
||||
#include "exec/address-spaces.h"
|
||||
|
||||
@ -114,12 +115,18 @@
|
||||
#define PSIHB_BAR_MASK 0x0003fffffff00000ull
|
||||
#define PSIHB_FSPBAR_MASK 0x0003ffff00000000ull
|
||||
|
||||
#define PSIHB9_BAR_MASK 0x00fffffffff00000ull
|
||||
#define PSIHB9_FSPBAR_MASK 0x00ffffff00000000ull
|
||||
|
||||
#define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR)
|
||||
|
||||
static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
|
||||
{
|
||||
PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi);
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
uint64_t old = psi->regs[PSIHB_XSCOM_BAR];
|
||||
|
||||
psi->regs[PSIHB_XSCOM_BAR] = bar & (PSIHB_BAR_MASK | PSIHB_BAR_EN);
|
||||
psi->regs[PSIHB_XSCOM_BAR] = bar & (ppc->bar_mask | PSIHB_BAR_EN);
|
||||
|
||||
/* Update MR, always remove it first */
|
||||
if (old & PSIHB_BAR_EN) {
|
||||
@ -128,7 +135,7 @@ static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar)
|
||||
|
||||
/* Then add it back if needed */
|
||||
if (bar & PSIHB_BAR_EN) {
|
||||
uint64_t addr = bar & PSIHB_BAR_MASK;
|
||||
uint64_t addr = bar & ppc->bar_mask;
|
||||
memory_region_add_subregion(sysmem, addr, &psi->regs_mr);
|
||||
}
|
||||
}
|
||||
@ -152,7 +159,7 @@ static void pnv_psi_set_cr(PnvPsi *psi, uint64_t cr)
|
||||
|
||||
static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
|
||||
{
|
||||
ICSState *ics = &psi->ics;
|
||||
ICSState *ics = &PNV8_PSI(psi)->ics;
|
||||
|
||||
/* In this model we ignore the up/down enable bits for now
|
||||
* as SW doesn't use them (other than setting them at boot).
|
||||
@ -205,7 +212,12 @@ static const uint64_t stat_bits[] = {
|
||||
[PSIHB_IRQ_EXTERNAL] = PSIHB_IRQ_STAT_EXT,
|
||||
};
|
||||
|
||||
void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
|
||||
void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
|
||||
{
|
||||
PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
|
||||
}
|
||||
|
||||
static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
|
||||
{
|
||||
uint32_t xivr_reg;
|
||||
uint32_t stat_reg;
|
||||
@ -260,7 +272,7 @@ void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
|
||||
|
||||
static void pnv_psi_set_xivr(PnvPsi *psi, uint32_t reg, uint64_t val)
|
||||
{
|
||||
ICSState *ics = &psi->ics;
|
||||
ICSState *ics = &PNV8_PSI(psi)->ics;
|
||||
uint16_t server;
|
||||
uint8_t prio;
|
||||
uint8_t src;
|
||||
@ -323,7 +335,7 @@ static uint64_t pnv_psi_reg_read(PnvPsi *psi, uint32_t offset, bool mmio)
|
||||
val = psi->regs[offset];
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "PSI: read at Ox%" PRIx32 "\n", offset);
|
||||
qemu_log_mask(LOG_UNIMP, "PSI: read at 0x%" PRIx32 "\n", offset);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@ -382,7 +394,7 @@ static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
|
||||
pnv_psi_set_irsn(psi, val);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "PSI: write at Ox%" PRIx32 "\n", offset);
|
||||
qemu_log_mask(LOG_UNIMP, "PSI: write at 0x%" PRIx32 "\n", offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,13 +404,13 @@ static void pnv_psi_reg_write(PnvPsi *psi, uint32_t offset, uint64_t val,
|
||||
*/
|
||||
static uint64_t pnv_psi_mmio_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
return pnv_psi_reg_read(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, true);
|
||||
return pnv_psi_reg_read(opaque, PSIHB_REG(addr), true);
|
||||
}
|
||||
|
||||
static void pnv_psi_mmio_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
pnv_psi_reg_write(opaque, (addr >> 3) + PSIHB_XSCOM_BAR, val, true);
|
||||
pnv_psi_reg_write(opaque, PSIHB_REG(addr), val, true);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps psi_mmio_ops = {
|
||||
@ -440,11 +452,20 @@ static const MemoryRegionOps pnv_psi_xscom_ops = {
|
||||
}
|
||||
};
|
||||
|
||||
static void pnv_psi_init(Object *obj)
|
||||
static void pnv_psi_reset(void *dev)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(obj);
|
||||
PnvPsi *psi = PNV_PSI(dev);
|
||||
|
||||
object_initialize_child(obj, "ics-psi", &psi->ics, sizeof(psi->ics),
|
||||
memset(psi->regs, 0x0, sizeof(psi->regs));
|
||||
|
||||
psi->regs[PSIHB_XSCOM_BAR] = psi->bar | PSIHB_BAR_EN;
|
||||
}
|
||||
|
||||
static void pnv_psi_power8_instance_init(Object *obj)
|
||||
{
|
||||
Pnv8Psi *psi8 = PNV8_PSI(obj);
|
||||
|
||||
object_initialize_child(obj, "ics-psi", &psi8->ics, sizeof(psi8->ics),
|
||||
TYPE_ICS_SIMPLE, &error_abort, NULL);
|
||||
}
|
||||
|
||||
@ -457,10 +478,10 @@ static const uint8_t irq_to_xivr[] = {
|
||||
PSIHB_XSCOM_XIVR_EXT,
|
||||
};
|
||||
|
||||
static void pnv_psi_realize(DeviceState *dev, Error **errp)
|
||||
static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(dev);
|
||||
ICSState *ics = &psi->ics;
|
||||
ICSState *ics = &PNV8_PSI(psi)->ics;
|
||||
Object *obj;
|
||||
Error *err = NULL;
|
||||
unsigned int i;
|
||||
@ -509,30 +530,38 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
|
||||
psi->regs[xivr] = PSIHB_XIVR_PRIO_MSK |
|
||||
((uint64_t) i << PSIHB_XIVR_SRC_SH);
|
||||
}
|
||||
|
||||
qemu_register_reset(pnv_psi_reset, dev);
|
||||
}
|
||||
|
||||
static const char compat_p8[] = "ibm,power8-psihb-x\0ibm,psihb-x";
|
||||
static const char compat_p9[] = "ibm,power9-psihb-x\0ibm,psihb-x";
|
||||
|
||||
static int pnv_psi_dt_xscom(PnvXScomInterface *dev, void *fdt, int xscom_offset)
|
||||
{
|
||||
const char compat[] = "ibm,power8-psihb-x\0ibm,psihb-x";
|
||||
PnvPsiClass *ppc = PNV_PSI_GET_CLASS(dev);
|
||||
char *name;
|
||||
int offset;
|
||||
uint32_t lpc_pcba = PNV_XSCOM_PSIHB_BASE;
|
||||
uint32_t reg[] = {
|
||||
cpu_to_be32(lpc_pcba),
|
||||
cpu_to_be32(PNV_XSCOM_PSIHB_SIZE)
|
||||
cpu_to_be32(ppc->xscom_pcba),
|
||||
cpu_to_be32(ppc->xscom_size)
|
||||
};
|
||||
|
||||
name = g_strdup_printf("psihb@%x", lpc_pcba);
|
||||
name = g_strdup_printf("psihb@%x", ppc->xscom_pcba);
|
||||
offset = fdt_add_subnode(fdt, xscom_offset, name);
|
||||
_FDT(offset);
|
||||
g_free(name);
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "reg", reg, sizeof(reg))));
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 2)));
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 1)));
|
||||
_FDT((fdt_setprop(fdt, offset, "compatible", compat,
|
||||
sizeof(compat))));
|
||||
_FDT(fdt_setprop(fdt, offset, "reg", reg, sizeof(reg)));
|
||||
_FDT(fdt_setprop_cell(fdt, offset, "#address-cells", 2));
|
||||
_FDT(fdt_setprop_cell(fdt, offset, "#size-cells", 1));
|
||||
if (ppc->chip_type == PNV_CHIP_POWER9) {
|
||||
_FDT(fdt_setprop(fdt, offset, "compatible", compat_p9,
|
||||
sizeof(compat_p9)));
|
||||
} else {
|
||||
_FDT(fdt_setprop(fdt, offset, "compatible", compat_p8,
|
||||
sizeof(compat_p8)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -542,6 +571,331 @@ static Property pnv_psi_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
|
||||
|
||||
dc->desc = "PowerNV PSI Controller POWER8";
|
||||
dc->realize = pnv_psi_power8_realize;
|
||||
|
||||
ppc->chip_type = PNV_CHIP_POWER8;
|
||||
ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
|
||||
ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
|
||||
ppc->bar_mask = PSIHB_BAR_MASK;
|
||||
ppc->irq_set = pnv_psi_power8_irq_set;
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_psi_power8_info = {
|
||||
.name = TYPE_PNV8_PSI,
|
||||
.parent = TYPE_PNV_PSI,
|
||||
.instance_size = sizeof(Pnv8Psi),
|
||||
.instance_init = pnv_psi_power8_instance_init,
|
||||
.class_init = pnv_psi_power8_class_init,
|
||||
};
|
||||
|
||||
|
||||
/* Common registers */
|
||||
|
||||
#define PSIHB9_CR 0x20
|
||||
#define PSIHB9_SEMR 0x28
|
||||
|
||||
/* P9 registers */
|
||||
|
||||
#define PSIHB9_INTERRUPT_CONTROL 0x58
|
||||
#define PSIHB9_IRQ_METHOD PPC_BIT(0)
|
||||
#define PSIHB9_IRQ_RESET PPC_BIT(1)
|
||||
#define PSIHB9_ESB_CI_BASE 0x60
|
||||
#define PSIHB9_ESB_CI_VALID 1
|
||||
#define PSIHB9_ESB_NOTIF_ADDR 0x68
|
||||
#define PSIHB9_ESB_NOTIF_VALID 1
|
||||
#define PSIHB9_IVT_OFFSET 0x70
|
||||
#define PSIHB9_IVT_OFF_SHIFT 32
|
||||
|
||||
#define PSIHB9_IRQ_LEVEL 0x78 /* assertion */
|
||||
#define PSIHB9_IRQ_LEVEL_PSI PPC_BIT(0)
|
||||
#define PSIHB9_IRQ_LEVEL_OCC PPC_BIT(1)
|
||||
#define PSIHB9_IRQ_LEVEL_FSI PPC_BIT(2)
|
||||
#define PSIHB9_IRQ_LEVEL_LPCHC PPC_BIT(3)
|
||||
#define PSIHB9_IRQ_LEVEL_LOCAL_ERR PPC_BIT(4)
|
||||
#define PSIHB9_IRQ_LEVEL_GLOBAL_ERR PPC_BIT(5)
|
||||
#define PSIHB9_IRQ_LEVEL_TPM PPC_BIT(6)
|
||||
#define PSIHB9_IRQ_LEVEL_LPC_SIRQ1 PPC_BIT(7)
|
||||
#define PSIHB9_IRQ_LEVEL_LPC_SIRQ2 PPC_BIT(8)
|
||||
#define PSIHB9_IRQ_LEVEL_LPC_SIRQ3 PPC_BIT(9)
|
||||
#define PSIHB9_IRQ_LEVEL_LPC_SIRQ4 PPC_BIT(10)
|
||||
#define PSIHB9_IRQ_LEVEL_SBE_I2C PPC_BIT(11)
|
||||
#define PSIHB9_IRQ_LEVEL_DIO PPC_BIT(12)
|
||||
#define PSIHB9_IRQ_LEVEL_PSU PPC_BIT(13)
|
||||
#define PSIHB9_IRQ_LEVEL_I2C_C PPC_BIT(14)
|
||||
#define PSIHB9_IRQ_LEVEL_I2C_D PPC_BIT(15)
|
||||
#define PSIHB9_IRQ_LEVEL_I2C_E PPC_BIT(16)
|
||||
#define PSIHB9_IRQ_LEVEL_SBE PPC_BIT(19)
|
||||
|
||||
#define PSIHB9_IRQ_STAT 0x80 /* P bit */
|
||||
#define PSIHB9_IRQ_STAT_PSI PPC_BIT(0)
|
||||
#define PSIHB9_IRQ_STAT_OCC PPC_BIT(1)
|
||||
#define PSIHB9_IRQ_STAT_FSI PPC_BIT(2)
|
||||
#define PSIHB9_IRQ_STAT_LPCHC PPC_BIT(3)
|
||||
#define PSIHB9_IRQ_STAT_LOCAL_ERR PPC_BIT(4)
|
||||
#define PSIHB9_IRQ_STAT_GLOBAL_ERR PPC_BIT(5)
|
||||
#define PSIHB9_IRQ_STAT_TPM PPC_BIT(6)
|
||||
#define PSIHB9_IRQ_STAT_LPC_SIRQ1 PPC_BIT(7)
|
||||
#define PSIHB9_IRQ_STAT_LPC_SIRQ2 PPC_BIT(8)
|
||||
#define PSIHB9_IRQ_STAT_LPC_SIRQ3 PPC_BIT(9)
|
||||
#define PSIHB9_IRQ_STAT_LPC_SIRQ4 PPC_BIT(10)
|
||||
#define PSIHB9_IRQ_STAT_SBE_I2C PPC_BIT(11)
|
||||
#define PSIHB9_IRQ_STAT_DIO PPC_BIT(12)
|
||||
#define PSIHB9_IRQ_STAT_PSU PPC_BIT(13)
|
||||
|
||||
static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(xf);
|
||||
uint64_t notif_port = psi->regs[PSIHB_REG(PSIHB9_ESB_NOTIF_ADDR)];
|
||||
bool valid = notif_port & PSIHB9_ESB_NOTIF_VALID;
|
||||
uint64_t notify_addr = notif_port & ~PSIHB9_ESB_NOTIF_VALID;
|
||||
|
||||
uint32_t offset =
|
||||
(psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
|
||||
uint64_t lisn = cpu_to_be64(offset + srcno);
|
||||
|
||||
if (valid) {
|
||||
cpu_physical_memory_write(notify_addr, &lisn, sizeof(lisn));
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t pnv_psi_p9_mmio_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(opaque);
|
||||
uint32_t reg = PSIHB_REG(addr);
|
||||
uint64_t val = -1;
|
||||
|
||||
switch (addr) {
|
||||
case PSIHB9_CR:
|
||||
case PSIHB9_SEMR:
|
||||
/* FSP stuff */
|
||||
case PSIHB9_INTERRUPT_CONTROL:
|
||||
case PSIHB9_ESB_CI_BASE:
|
||||
case PSIHB9_ESB_NOTIF_ADDR:
|
||||
case PSIHB9_IVT_OFFSET:
|
||||
val = psi->regs[reg];
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: read at 0x%" PRIx64 "\n", addr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(opaque);
|
||||
Pnv9Psi *psi9 = PNV9_PSI(psi);
|
||||
uint32_t reg = PSIHB_REG(addr);
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
|
||||
switch (addr) {
|
||||
case PSIHB9_CR:
|
||||
case PSIHB9_SEMR:
|
||||
/* FSP stuff */
|
||||
break;
|
||||
case PSIHB9_INTERRUPT_CONTROL:
|
||||
if (val & PSIHB9_IRQ_RESET) {
|
||||
device_reset(DEVICE(&psi9->source));
|
||||
}
|
||||
psi->regs[reg] = val;
|
||||
break;
|
||||
|
||||
case PSIHB9_ESB_CI_BASE:
|
||||
if (!(val & PSIHB9_ESB_CI_VALID)) {
|
||||
if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
|
||||
memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
|
||||
}
|
||||
} else {
|
||||
if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
|
||||
memory_region_add_subregion(sysmem,
|
||||
val & ~PSIHB9_ESB_CI_VALID,
|
||||
&psi9->source.esb_mmio);
|
||||
}
|
||||
}
|
||||
psi->regs[reg] = val;
|
||||
break;
|
||||
|
||||
case PSIHB9_ESB_NOTIF_ADDR:
|
||||
psi->regs[reg] = val;
|
||||
break;
|
||||
case PSIHB9_IVT_OFFSET:
|
||||
psi->regs[reg] = val;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: write at 0x%" PRIx64 "\n", addr);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_psi_p9_mmio_ops = {
|
||||
.read = pnv_psi_p9_mmio_read,
|
||||
.write = pnv_psi_p9_mmio_write,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 8,
|
||||
.max_access_size = 8,
|
||||
},
|
||||
.impl = {
|
||||
.min_access_size = 8,
|
||||
.max_access_size = 8,
|
||||
},
|
||||
};
|
||||
|
||||
static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
/* No read are expected */
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom read at 0x%" PRIx64 "\n", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr,
|
||||
uint64_t val, unsigned size)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(opaque);
|
||||
|
||||
/* XSCOM is only used to set the PSIHB MMIO region */
|
||||
switch (addr >> 3) {
|
||||
case PSIHB_XSCOM_BAR:
|
||||
pnv_psi_set_bar(psi, val);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom write at 0x%" PRIx64 "\n",
|
||||
addr);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
|
||||
.read = pnv_psi_p9_xscom_read,
|
||||
.write = pnv_psi_p9_xscom_write,
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 8,
|
||||
.max_access_size = 8,
|
||||
},
|
||||
.impl = {
|
||||
.min_access_size = 8,
|
||||
.max_access_size = 8,
|
||||
}
|
||||
};
|
||||
|
||||
static void pnv_psi_power9_irq_set(PnvPsi *psi, int irq, bool state)
|
||||
{
|
||||
uint32_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];
|
||||
|
||||
if (irq > PSIHB9_NUM_IRQS) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irq_method & PSIHB9_IRQ_METHOD) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update LSI levels */
|
||||
if (state) {
|
||||
psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] |= PPC_BIT(irq);
|
||||
} else {
|
||||
psi->regs[PSIHB_REG(PSIHB9_IRQ_LEVEL)] &= ~PPC_BIT(irq);
|
||||
}
|
||||
|
||||
qemu_set_irq(psi->qirqs[irq], state);
|
||||
}
|
||||
|
||||
static void pnv_psi_power9_reset(void *dev)
|
||||
{
|
||||
Pnv9Psi *psi = PNV9_PSI(dev);
|
||||
|
||||
pnv_psi_reset(dev);
|
||||
|
||||
if (memory_region_is_mapped(&psi->source.esb_mmio)) {
|
||||
memory_region_del_subregion(get_system_memory(), &psi->source.esb_mmio);
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_psi_power9_instance_init(Object *obj)
|
||||
{
|
||||
Pnv9Psi *psi = PNV9_PSI(obj);
|
||||
|
||||
object_initialize_child(obj, "source", &psi->source, sizeof(psi->source),
|
||||
TYPE_XIVE_SOURCE, &error_abort, NULL);
|
||||
}
|
||||
|
||||
static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(dev);
|
||||
XiveSource *xsrc = &PNV9_PSI(psi)->source;
|
||||
Error *local_err = NULL;
|
||||
int i;
|
||||
|
||||
/* This is the only device with 4k ESB pages */
|
||||
object_property_set_int(OBJECT(xsrc), XIVE_ESB_4K, "shift",
|
||||
&error_fatal);
|
||||
object_property_set_int(OBJECT(xsrc), PSIHB9_NUM_IRQS, "nr-irqs",
|
||||
&error_fatal);
|
||||
object_property_add_const_link(OBJECT(xsrc), "xive", OBJECT(psi),
|
||||
&error_fatal);
|
||||
object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < xsrc->nr_irqs; i++) {
|
||||
xive_source_irq_set_lsi(xsrc, i);
|
||||
}
|
||||
|
||||
psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
|
||||
|
||||
/* XSCOM region for PSI registers */
|
||||
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
|
||||
psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
|
||||
|
||||
/* MMIO region for PSI registers */
|
||||
memory_region_init_io(&psi->regs_mr, OBJECT(dev), &pnv_psi_p9_mmio_ops, psi,
|
||||
"psihb", PNV9_PSIHB_SIZE);
|
||||
|
||||
pnv_psi_set_bar(psi, psi->bar | PSIHB_BAR_EN);
|
||||
|
||||
qemu_register_reset(pnv_psi_power9_reset, dev);
|
||||
}
|
||||
|
||||
static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvPsiClass *ppc = PNV_PSI_CLASS(klass);
|
||||
XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass);
|
||||
|
||||
dc->desc = "PowerNV PSI Controller POWER9";
|
||||
dc->realize = pnv_psi_power9_realize;
|
||||
|
||||
ppc->chip_type = PNV_CHIP_POWER9;
|
||||
ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
|
||||
ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
|
||||
ppc->bar_mask = PSIHB9_BAR_MASK;
|
||||
ppc->irq_set = pnv_psi_power9_irq_set;
|
||||
|
||||
xfc->notify = pnv_psi_notify;
|
||||
}
|
||||
|
||||
static const TypeInfo pnv_psi_power9_info = {
|
||||
.name = TYPE_PNV9_PSI,
|
||||
.parent = TYPE_PNV_PSI,
|
||||
.instance_size = sizeof(Pnv9Psi),
|
||||
.instance_init = pnv_psi_power9_instance_init,
|
||||
.class_init = pnv_psi_power9_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_XIVE_NOTIFIER },
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static void pnv_psi_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@ -549,7 +903,7 @@ static void pnv_psi_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
xdc->dt_xscom = pnv_psi_dt_xscom;
|
||||
|
||||
dc->realize = pnv_psi_realize;
|
||||
dc->desc = "PowerNV PSI Controller";
|
||||
dc->props = pnv_psi_properties;
|
||||
}
|
||||
|
||||
@ -557,8 +911,9 @@ static const TypeInfo pnv_psi_info = {
|
||||
.name = TYPE_PNV_PSI,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(PnvPsi),
|
||||
.instance_init = pnv_psi_init,
|
||||
.class_init = pnv_psi_class_init,
|
||||
.class_size = sizeof(PnvPsiClass),
|
||||
.abstract = true,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_PNV_XSCOM_INTERFACE },
|
||||
{ }
|
||||
@ -568,6 +923,20 @@ static const TypeInfo pnv_psi_info = {
|
||||
static void pnv_psi_register_types(void)
|
||||
{
|
||||
type_register_static(&pnv_psi_info);
|
||||
type_register_static(&pnv_psi_power8_info);
|
||||
type_register_static(&pnv_psi_power9_info);
|
||||
}
|
||||
|
||||
type_init(pnv_psi_register_types)
|
||||
type_init(pnv_psi_register_types);
|
||||
|
||||
void pnv_psi_pic_print_info(Pnv9Psi *psi9, Monitor *mon)
|
||||
{
|
||||
PnvPsi *psi = PNV_PSI(psi9);
|
||||
|
||||
uint32_t offset =
|
||||
(psi->regs[PSIHB_REG(PSIHB9_IVT_OFFSET)] >> PSIHB9_IVT_OFF_SHIFT);
|
||||
|
||||
monitor_printf(mon, "PSIHB Source %08x .. %08x\n",
|
||||
offset, offset + psi9->source.nr_irqs - 1);
|
||||
xive_source_pic_print_info(&psi9->source, offset, mon);
|
||||
}
|
||||
|
@ -64,11 +64,21 @@ static uint64_t xscom_read_default(PnvChip *chip, uint32_t pcba)
|
||||
switch (pcba) {
|
||||
case 0xf000f:
|
||||
return PNV_CHIP_GET_CLASS(chip)->chip_cfam_id;
|
||||
case 0x18002: /* ECID2 */
|
||||
return 0;
|
||||
|
||||
case 0x1010c00: /* PIBAM FIR */
|
||||
case 0x1010c03: /* PIBAM FIR MASK */
|
||||
case 0x2020007: /* ADU stuff */
|
||||
case 0x2020009: /* ADU stuff */
|
||||
case 0x202000f: /* ADU stuff */
|
||||
|
||||
/* P9 xscom reset */
|
||||
case 0x0090018: /* Receive status reg */
|
||||
case 0x0090012: /* log register */
|
||||
case 0x0090013: /* error register */
|
||||
|
||||
/* P8 xscom reset */
|
||||
case 0x2020007: /* ADU stuff, log register */
|
||||
case 0x2020009: /* ADU stuff, error register */
|
||||
case 0x202000f: /* ADU stuff, receive status register*/
|
||||
return 0;
|
||||
case 0x2013f00: /* PBA stuff */
|
||||
case 0x2013f01: /* PBA stuff */
|
||||
@ -100,9 +110,20 @@ static bool xscom_write_default(PnvChip *chip, uint32_t pcba, uint64_t val)
|
||||
case 0x1010c03: /* PIBAM FIR MASK */
|
||||
case 0x1010c04: /* PIBAM FIR MASK */
|
||||
case 0x1010c05: /* PIBAM FIR MASK */
|
||||
case 0x2020007: /* ADU stuff */
|
||||
case 0x2020009: /* ADU stuff */
|
||||
case 0x202000f: /* ADU stuff */
|
||||
/* P9 xscom reset */
|
||||
case 0x0090018: /* Receive status reg */
|
||||
case 0x0090012: /* log register */
|
||||
case 0x0090013: /* error register */
|
||||
|
||||
/* P8 xscom reset */
|
||||
case 0x2020007: /* ADU stuff, log register */
|
||||
case 0x2020009: /* ADU stuff, error register */
|
||||
case 0x202000f: /* ADU stuff, receive status register*/
|
||||
|
||||
case 0x2013028: /* CAPP stuff */
|
||||
case 0x201302a: /* CAPP stuff */
|
||||
case 0x2013801: /* CAPP stuff */
|
||||
case 0x2013802: /* CAPP stuff */
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
106
hw/ppc/ppc.c
106
hw/ppc/ppc.c
@ -744,11 +744,10 @@ bool ppc_decr_clear_on_delivery(CPUPPCState *env)
|
||||
return ((tb_env->flags & flags) == PPC_DECR_UNDERFLOW_TRIGGERED);
|
||||
}
|
||||
|
||||
static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
|
||||
static inline int64_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
|
||||
{
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
uint32_t decr;
|
||||
int64_t diff;
|
||||
int64_t decr, diff;
|
||||
|
||||
diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
if (diff >= 0) {
|
||||
@ -758,27 +757,49 @@ static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
|
||||
} else {
|
||||
decr = -muldiv64(-diff, tb_env->decr_freq, NANOSECONDS_PER_SECOND);
|
||||
}
|
||||
LOG_TB("%s: %08" PRIx32 "\n", __func__, decr);
|
||||
LOG_TB("%s: %016" PRIx64 "\n", __func__, decr);
|
||||
|
||||
return decr;
|
||||
}
|
||||
|
||||
uint32_t cpu_ppc_load_decr (CPUPPCState *env)
|
||||
target_ulong cpu_ppc_load_decr(CPUPPCState *env)
|
||||
{
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
uint64_t decr;
|
||||
|
||||
if (kvm_enabled()) {
|
||||
return env->spr[SPR_DECR];
|
||||
}
|
||||
|
||||
return _cpu_ppc_load_decr(env, tb_env->decr_next);
|
||||
decr = _cpu_ppc_load_decr(env, tb_env->decr_next);
|
||||
|
||||
/*
|
||||
* If large decrementer is enabled then the decrementer is signed extened
|
||||
* to 64 bits, otherwise it is a 32 bit value.
|
||||
*/
|
||||
if (env->spr[SPR_LPCR] & LPCR_LD) {
|
||||
return decr;
|
||||
}
|
||||
return (uint32_t) decr;
|
||||
}
|
||||
|
||||
uint32_t cpu_ppc_load_hdecr (CPUPPCState *env)
|
||||
target_ulong cpu_ppc_load_hdecr(CPUPPCState *env)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
uint64_t hdecr;
|
||||
|
||||
return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
|
||||
hdecr = _cpu_ppc_load_decr(env, tb_env->hdecr_next);
|
||||
|
||||
/*
|
||||
* If we have a large decrementer (POWER9 or later) then hdecr is sign
|
||||
* extended to 64 bits, otherwise it is 32 bits.
|
||||
*/
|
||||
if (pcc->lrg_decr_bits > 32) {
|
||||
return hdecr;
|
||||
}
|
||||
return (uint32_t) hdecr;
|
||||
}
|
||||
|
||||
uint64_t cpu_ppc_load_purr (CPUPPCState *env)
|
||||
@ -832,13 +853,22 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
|
||||
QEMUTimer *timer,
|
||||
void (*raise_excp)(void *),
|
||||
void (*lower_excp)(PowerPCCPU *),
|
||||
uint32_t decr, uint32_t value)
|
||||
target_ulong decr, target_ulong value,
|
||||
int nr_bits)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
uint64_t now, next;
|
||||
bool negative;
|
||||
|
||||
LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__,
|
||||
/* Truncate value to decr_width and sign extend for simplicity */
|
||||
value &= ((1ULL << nr_bits) - 1);
|
||||
negative = !!(value & (1ULL << (nr_bits - 1)));
|
||||
if (negative) {
|
||||
value |= (0xFFFFFFFFULL << nr_bits);
|
||||
}
|
||||
|
||||
LOG_TB("%s: " TARGET_FMT_lx " => " TARGET_FMT_lx "\n", __func__,
|
||||
decr, value);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
@ -860,15 +890,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
|
||||
* an edge interrupt, so raise it here too.
|
||||
*/
|
||||
if ((value < 3) ||
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && (value & 0x80000000)) ||
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && (value & 0x80000000)
|
||||
&& !(decr & 0x80000000))) {
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && negative) ||
|
||||
((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && negative
|
||||
&& !(decr & (1ULL << (nr_bits - 1))))) {
|
||||
(*raise_excp)(cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
/* On MSB level based systems a 0 for the MSB stops interrupt delivery */
|
||||
if (!(value & 0x80000000) && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
|
||||
if (!negative && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) {
|
||||
(*lower_excp)(cpu);
|
||||
}
|
||||
|
||||
@ -881,21 +911,27 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
|
||||
timer_mod(timer, next);
|
||||
}
|
||||
|
||||
static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr,
|
||||
uint32_t value)
|
||||
static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr,
|
||||
target_ulong value, int nr_bits)
|
||||
{
|
||||
ppc_tb_t *tb_env = cpu->env.tb_env;
|
||||
|
||||
__cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer,
|
||||
tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr,
|
||||
value);
|
||||
value, nr_bits);
|
||||
}
|
||||
|
||||
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value)
|
||||
void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
int nr_bits = 32;
|
||||
|
||||
_cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value);
|
||||
if (env->spr[SPR_LPCR] & LPCR_LD) {
|
||||
nr_bits = pcc->lrg_decr_bits;
|
||||
}
|
||||
|
||||
_cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, nr_bits);
|
||||
}
|
||||
|
||||
static void cpu_ppc_decr_cb(void *opaque)
|
||||
@ -905,23 +941,25 @@ static void cpu_ppc_decr_cb(void *opaque)
|
||||
cpu_ppc_decr_excp(cpu);
|
||||
}
|
||||
|
||||
static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr,
|
||||
uint32_t value)
|
||||
static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr,
|
||||
target_ulong value, int nr_bits)
|
||||
{
|
||||
ppc_tb_t *tb_env = cpu->env.tb_env;
|
||||
|
||||
if (tb_env->hdecr_timer != NULL) {
|
||||
__cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer,
|
||||
tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower,
|
||||
hdecr, value);
|
||||
hdecr, value, nr_bits);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)
|
||||
void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
|
||||
_cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value);
|
||||
_cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value,
|
||||
pcc->lrg_decr_bits);
|
||||
}
|
||||
|
||||
static void cpu_ppc_hdecr_cb(void *opaque)
|
||||
@ -951,8 +989,8 @@ static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
|
||||
* if a decrementer exception is pending when it enables msr_ee at startup,
|
||||
* it's not ready to handle it...
|
||||
*/
|
||||
_cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
_cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
_cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
|
||||
_cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 32);
|
||||
cpu_ppc_store_purr(cpu, 0x0000000000000000ULL);
|
||||
}
|
||||
|
||||
@ -1454,3 +1492,19 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PowerPCCPU *ppc_get_vcpu_by_pir(int pir)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
CPU_FOREACH(cs) {
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
if (env->spr_cb[SPR_PIR].default_value == pir) {
|
||||
return cpu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
361
hw/ppc/spapr.c
361
hw/ppc/spapr.c
File diff suppressed because it is too large
Load Diff
@ -31,10 +31,11 @@
|
||||
#include "target/ppc/mmu-hash64.h"
|
||||
#include "cpu-models.h"
|
||||
#include "kvm_ppc.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
#include "hw/ppc/spapr.h"
|
||||
|
||||
typedef struct sPAPRCapPossible {
|
||||
typedef struct SpaprCapPossible {
|
||||
int num; /* size of vals array below */
|
||||
const char *help; /* help text for vals */
|
||||
/*
|
||||
@ -46,9 +47,9 @@ typedef struct sPAPRCapPossible {
|
||||
* point is observed
|
||||
*/
|
||||
const char *vals[];
|
||||
} sPAPRCapPossible;
|
||||
} SpaprCapPossible;
|
||||
|
||||
typedef struct sPAPRCapabilityInfo {
|
||||
typedef struct SpaprCapabilityInfo {
|
||||
const char *name;
|
||||
const char *description;
|
||||
int index;
|
||||
@ -58,18 +59,18 @@ typedef struct sPAPRCapabilityInfo {
|
||||
ObjectPropertyAccessor *set;
|
||||
const char *type;
|
||||
/* Possible values if this is a custom string type */
|
||||
sPAPRCapPossible *possible;
|
||||
SpaprCapPossible *possible;
|
||||
/* Make sure the virtual hardware can support this capability */
|
||||
void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp);
|
||||
void (*cpu_apply)(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
||||
void (*apply)(SpaprMachineState *spapr, uint8_t val, Error **errp);
|
||||
void (*cpu_apply)(SpaprMachineState *spapr, PowerPCCPU *cpu,
|
||||
uint8_t val, Error **errp);
|
||||
} sPAPRCapabilityInfo;
|
||||
} SpaprCapabilityInfo;
|
||||
|
||||
static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
|
||||
|
||||
visit_type_bool(v, name, &value, errp);
|
||||
@ -78,8 +79,8 @@ static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
|
||||
static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
bool value;
|
||||
Error *local_err = NULL;
|
||||
|
||||
@ -97,8 +98,8 @@ static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
|
||||
static void spapr_cap_get_string(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
char *val = NULL;
|
||||
uint8_t value = spapr_get_cap(spapr, cap->index);
|
||||
|
||||
@ -116,8 +117,8 @@ static void spapr_cap_get_string(Object *obj, Visitor *v, const char *name,
|
||||
static void spapr_cap_set_string(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
Error *local_err = NULL;
|
||||
uint8_t i;
|
||||
char *val;
|
||||
@ -149,8 +150,8 @@ out:
|
||||
static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
uint8_t val = spapr_get_cap(spapr, cap->index);
|
||||
uint64_t pagesize = (1ULL << val);
|
||||
|
||||
@ -160,8 +161,8 @@ static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name,
|
||||
static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRCapabilityInfo *cap = opaque;
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
SpaprCapabilityInfo *cap = opaque;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
|
||||
uint64_t pagesize;
|
||||
uint8_t val;
|
||||
Error *local_err = NULL;
|
||||
@ -182,7 +183,7 @@ static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name,
|
||||
spapr->eff.caps[cap->index] = val;
|
||||
}
|
||||
|
||||
static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
static void cap_htm_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
|
||||
{
|
||||
if (!val) {
|
||||
/* TODO: We don't support disabling htm yet */
|
||||
@ -198,7 +199,7 @@ static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
static void cap_vsx_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -215,7 +216,7 @@ static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
static void cap_dfp_apply(SpaprMachineState *spapr, uint8_t val, Error **errp)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -229,83 +230,97 @@ static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
sPAPRCapPossible cap_cfpc_possible = {
|
||||
SpaprCapPossible cap_cfpc_possible = {
|
||||
.num = 3,
|
||||
.vals = {"broken", "workaround", "fixed"},
|
||||
.help = "broken - no protection, workaround - workaround available,"
|
||||
" fixed - fixed in hardware",
|
||||
};
|
||||
|
||||
static void cap_safe_cache_apply(sPAPRMachineState *spapr, uint8_t val,
|
||||
static void cap_safe_cache_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
uint8_t kvm_val = kvmppc_get_cap_safe_cache();
|
||||
|
||||
if (tcg_enabled() && val) {
|
||||
/* TODO - for now only allow broken for TCG */
|
||||
error_setg(errp,
|
||||
"Requested safe cache capability level not supported by tcg, try a different value for cap-cfpc");
|
||||
/* TCG only supports broken, allow other values and print a warning */
|
||||
error_setg(&local_err,
|
||||
"TCG doesn't support requested feature, cap-cfpc=%s",
|
||||
cap_cfpc_possible.vals[val]);
|
||||
} else if (kvm_enabled() && (val > kvm_val)) {
|
||||
error_setg(errp,
|
||||
"Requested safe cache capability level not supported by kvm, try cap-cfpc=%s",
|
||||
cap_cfpc_possible.vals[kvm_val]);
|
||||
}
|
||||
|
||||
if (local_err != NULL)
|
||||
warn_report_err(local_err);
|
||||
}
|
||||
|
||||
sPAPRCapPossible cap_sbbc_possible = {
|
||||
SpaprCapPossible cap_sbbc_possible = {
|
||||
.num = 3,
|
||||
.vals = {"broken", "workaround", "fixed"},
|
||||
.help = "broken - no protection, workaround - workaround available,"
|
||||
" fixed - fixed in hardware",
|
||||
};
|
||||
|
||||
static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
|
||||
static void cap_safe_bounds_check_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
uint8_t kvm_val = kvmppc_get_cap_safe_bounds_check();
|
||||
|
||||
if (tcg_enabled() && val) {
|
||||
/* TODO - for now only allow broken for TCG */
|
||||
error_setg(errp,
|
||||
"Requested safe bounds check capability level not supported by tcg, try a different value for cap-sbbc");
|
||||
/* TCG only supports broken, allow other values and print a warning */
|
||||
error_setg(&local_err,
|
||||
"TCG doesn't support requested feature, cap-sbbc=%s",
|
||||
cap_sbbc_possible.vals[val]);
|
||||
} else if (kvm_enabled() && (val > kvm_val)) {
|
||||
error_setg(errp,
|
||||
"Requested safe bounds check capability level not supported by kvm, try cap-sbbc=%s",
|
||||
cap_sbbc_possible.vals[kvm_val]);
|
||||
}
|
||||
|
||||
if (local_err != NULL)
|
||||
warn_report_err(local_err);
|
||||
}
|
||||
|
||||
sPAPRCapPossible cap_ibs_possible = {
|
||||
.num = 4,
|
||||
SpaprCapPossible cap_ibs_possible = {
|
||||
.num = 5,
|
||||
/* Note workaround only maintained for compatibility */
|
||||
.vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd"},
|
||||
.help = "broken - no protection, fixed-ibs - indirect branch serialisation,"
|
||||
" fixed-ccd - cache count disabled",
|
||||
.vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
|
||||
.help = "broken - no protection, workaround - count cache flush"
|
||||
", fixed-ibs - indirect branch serialisation,"
|
||||
" fixed-ccd - cache count disabled,"
|
||||
" fixed-na - fixed in hardware (no longer applicable)",
|
||||
};
|
||||
|
||||
static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
|
||||
static void cap_safe_indirect_branch_apply(SpaprMachineState *spapr,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
|
||||
|
||||
if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */
|
||||
error_setg(errp,
|
||||
"Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=%s",
|
||||
cap_ibs_possible.vals[kvm_val]);
|
||||
} else if (tcg_enabled() && val) {
|
||||
/* TODO - for now only allow broken for TCG */
|
||||
error_setg(errp,
|
||||
"Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
|
||||
} else if (kvm_enabled() && val && (val != kvm_val)) {
|
||||
if (tcg_enabled() && val) {
|
||||
/* TCG only supports broken, allow other values and print a warning */
|
||||
error_setg(&local_err,
|
||||
"TCG doesn't support requested feature, cap-ibs=%s",
|
||||
cap_ibs_possible.vals[val]);
|
||||
} else if (kvm_enabled() && (val > kvm_val)) {
|
||||
error_setg(errp,
|
||||
"Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
|
||||
cap_ibs_possible.vals[kvm_val]);
|
||||
}
|
||||
|
||||
if (local_err != NULL) {
|
||||
warn_report_err(local_err);
|
||||
}
|
||||
}
|
||||
|
||||
#define VALUE_DESC_TRISTATE " (broken, workaround, fixed)"
|
||||
|
||||
void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
|
||||
void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
|
||||
Error **errp)
|
||||
{
|
||||
hwaddr maxpagesize = (1ULL << spapr->eff.caps[SPAPR_CAP_HPT_MAXPAGESIZE]);
|
||||
@ -322,7 +337,7 @@ void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr,
|
||||
static void cap_hpt_maxpagesize_apply(SpaprMachineState *spapr,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
if (val < 12) {
|
||||
@ -359,7 +374,7 @@ static bool spapr_pagesize_cb(void *opaque, uint32_t seg_pshift,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cap_hpt_maxpagesize_cpu_apply(sPAPRMachineState *spapr,
|
||||
static void cap_hpt_maxpagesize_cpu_apply(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
@ -368,7 +383,7 @@ static void cap_hpt_maxpagesize_cpu_apply(sPAPRMachineState *spapr,
|
||||
ppc_hash64_filter_pagesizes(cpu, spapr_pagesize_cb, &maxshift);
|
||||
}
|
||||
|
||||
static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
|
||||
static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
if (!val) {
|
||||
@ -390,7 +405,75 @@ static void cap_nested_kvm_hv_apply(sPAPRMachineState *spapr,
|
||||
}
|
||||
}
|
||||
|
||||
sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
||||
static void cap_large_decr_apply(SpaprMachineState *spapr,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
|
||||
if (!val) {
|
||||
return; /* Disabled by default */
|
||||
}
|
||||
|
||||
if (tcg_enabled()) {
|
||||
if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
|
||||
spapr->max_compat_pvr)) {
|
||||
error_setg(errp,
|
||||
"Large decrementer only supported on POWER9, try -cpu POWER9");
|
||||
return;
|
||||
}
|
||||
} else if (kvm_enabled()) {
|
||||
int kvm_nr_bits = kvmppc_get_cap_large_decr();
|
||||
|
||||
if (!kvm_nr_bits) {
|
||||
error_setg(errp,
|
||||
"No large decrementer support, try cap-large-decr=off");
|
||||
} else if (pcc->lrg_decr_bits != kvm_nr_bits) {
|
||||
error_setg(errp,
|
||||
"KVM large decrementer size (%d) differs to model (%d), try -cap-large-decr=off",
|
||||
kvm_nr_bits, pcc->lrg_decr_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_large_decr_cpu_apply(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
target_ulong lpcr = env->spr[SPR_LPCR];
|
||||
|
||||
if (kvm_enabled()) {
|
||||
if (kvmppc_enable_cap_large_decr(cpu, val)) {
|
||||
error_setg(errp,
|
||||
"No large decrementer support, try cap-large-decr=off");
|
||||
}
|
||||
}
|
||||
|
||||
if (val) {
|
||||
lpcr |= LPCR_LD;
|
||||
} else {
|
||||
lpcr &= ~LPCR_LD;
|
||||
}
|
||||
ppc_store_lpcr(cpu, lpcr);
|
||||
}
|
||||
|
||||
static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val,
|
||||
Error **errp)
|
||||
{
|
||||
uint8_t kvm_val = kvmppc_get_cap_count_cache_flush_assist();
|
||||
|
||||
if (tcg_enabled() && val) {
|
||||
/* TODO - for now only allow broken for TCG */
|
||||
error_setg(errp,
|
||||
"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off");
|
||||
} else if (kvm_enabled() && (val > kvm_val)) {
|
||||
error_setg(errp,
|
||||
"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off");
|
||||
}
|
||||
}
|
||||
|
||||
SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
||||
[SPAPR_CAP_HTM] = {
|
||||
.name = "htm",
|
||||
.description = "Allow Hardware Transactional Memory (HTM)",
|
||||
@ -441,7 +524,8 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
||||
[SPAPR_CAP_IBS] = {
|
||||
.name = "ibs",
|
||||
.description =
|
||||
"Indirect Branch Speculation (broken, fixed-ibs, fixed-ccd)",
|
||||
"Indirect Branch Speculation (broken, workaround, fixed-ibs,"
|
||||
"fixed-ccd, fixed-na)",
|
||||
.index = SPAPR_CAP_IBS,
|
||||
.get = spapr_cap_get_string,
|
||||
.set = spapr_cap_set_string,
|
||||
@ -468,16 +552,40 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
||||
.type = "bool",
|
||||
.apply = cap_nested_kvm_hv_apply,
|
||||
},
|
||||
[SPAPR_CAP_LARGE_DECREMENTER] = {
|
||||
.name = "large-decr",
|
||||
.description = "Allow Large Decrementer",
|
||||
.index = SPAPR_CAP_LARGE_DECREMENTER,
|
||||
.get = spapr_cap_get_bool,
|
||||
.set = spapr_cap_set_bool,
|
||||
.type = "bool",
|
||||
.apply = cap_large_decr_apply,
|
||||
.cpu_apply = cap_large_decr_cpu_apply,
|
||||
},
|
||||
[SPAPR_CAP_CCF_ASSIST] = {
|
||||
.name = "ccf-assist",
|
||||
.description = "Count Cache Flush Assist via HW Instruction",
|
||||
.index = SPAPR_CAP_CCF_ASSIST,
|
||||
.get = spapr_cap_get_bool,
|
||||
.set = spapr_cap_set_bool,
|
||||
.type = "bool",
|
||||
.apply = cap_ccf_assist_apply,
|
||||
},
|
||||
};
|
||||
|
||||
static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
|
||||
static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
|
||||
const char *cputype)
|
||||
{
|
||||
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
sPAPRCapabilities caps;
|
||||
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
SpaprCapabilities caps;
|
||||
|
||||
caps = smc->default_caps;
|
||||
|
||||
if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_00,
|
||||
0, spapr->max_compat_pvr)) {
|
||||
caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF;
|
||||
}
|
||||
|
||||
if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_07,
|
||||
0, spapr->max_compat_pvr)) {
|
||||
caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
|
||||
@ -514,7 +622,7 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
|
||||
|
||||
int spapr_caps_pre_load(void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
SpaprMachineState *spapr = opaque;
|
||||
|
||||
/* Set to default so we can tell if this came in with the migration */
|
||||
spapr->mig = spapr->def;
|
||||
@ -523,7 +631,7 @@ int spapr_caps_pre_load(void *opaque)
|
||||
|
||||
int spapr_caps_pre_save(void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
SpaprMachineState *spapr = opaque;
|
||||
|
||||
spapr->mig = spapr->eff;
|
||||
return 0;
|
||||
@ -533,12 +641,12 @@ int spapr_caps_pre_save(void *opaque)
|
||||
* caps specific one. Otherwise it wouldn't be called when the source
|
||||
* caps are all defaults, which could still conflict with overridden
|
||||
* caps on the destination */
|
||||
int spapr_caps_post_migration(sPAPRMachineState *spapr)
|
||||
int spapr_caps_post_migration(SpaprMachineState *spapr)
|
||||
{
|
||||
int i;
|
||||
bool ok = true;
|
||||
sPAPRCapabilities dstcaps = spapr->eff;
|
||||
sPAPRCapabilities srccaps;
|
||||
SpaprCapabilities dstcaps = spapr->eff;
|
||||
SpaprCapabilities srccaps;
|
||||
|
||||
srccaps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type);
|
||||
for (i = 0; i < SPAPR_CAP_NUM; i++) {
|
||||
@ -549,7 +657,7 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
|
||||
}
|
||||
|
||||
for (i = 0; i < SPAPR_CAP_NUM; i++) {
|
||||
sPAPRCapabilityInfo *info = &capability_table[i];
|
||||
SpaprCapabilityInfo *info = &capability_table[i];
|
||||
|
||||
if (srccaps.caps[i] > dstcaps.caps[i]) {
|
||||
error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
|
||||
@ -570,7 +678,7 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
|
||||
#define SPAPR_CAP_MIG_STATE(sname, cap) \
|
||||
static bool spapr_cap_##sname##_needed(void *opaque) \
|
||||
{ \
|
||||
sPAPRMachineState *spapr = opaque; \
|
||||
SpaprMachineState *spapr = opaque; \
|
||||
\
|
||||
return spapr->cmd_line_caps[cap] && \
|
||||
(spapr->eff.caps[cap] != \
|
||||
@ -584,7 +692,7 @@ const VMStateDescription vmstate_spapr_cap_##sname = { \
|
||||
.needed = spapr_cap_##sname##_needed, \
|
||||
.fields = (VMStateField[]) { \
|
||||
VMSTATE_UINT8(mig.caps[cap], \
|
||||
sPAPRMachineState), \
|
||||
SpaprMachineState), \
|
||||
VMSTATE_END_OF_LIST() \
|
||||
}, \
|
||||
}
|
||||
@ -596,10 +704,12 @@ SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC);
|
||||
SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
|
||||
SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
|
||||
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
|
||||
SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
|
||||
SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
|
||||
|
||||
void spapr_caps_init(sPAPRMachineState *spapr)
|
||||
void spapr_caps_init(SpaprMachineState *spapr)
|
||||
{
|
||||
sPAPRCapabilities default_caps;
|
||||
SpaprCapabilities default_caps;
|
||||
int i;
|
||||
|
||||
/* Compute the actual set of caps we should run with */
|
||||
@ -615,12 +725,12 @@ void spapr_caps_init(sPAPRMachineState *spapr)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_caps_apply(sPAPRMachineState *spapr)
|
||||
void spapr_caps_apply(SpaprMachineState *spapr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPAPR_CAP_NUM; i++) {
|
||||
sPAPRCapabilityInfo *info = &capability_table[i];
|
||||
SpaprCapabilityInfo *info = &capability_table[i];
|
||||
|
||||
/*
|
||||
* If the apply function can't set the desired level and thinks it's
|
||||
@ -630,12 +740,12 @@ void spapr_caps_apply(sPAPRMachineState *spapr)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu)
|
||||
void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SPAPR_CAP_NUM; i++) {
|
||||
sPAPRCapabilityInfo *info = &capability_table[i];
|
||||
SpaprCapabilityInfo *info = &capability_table[i];
|
||||
|
||||
/*
|
||||
* If the apply function can't set the desired level and thinks it's
|
||||
@ -647,14 +757,14 @@ void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
|
||||
void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
ObjectClass *klass = OBJECT_CLASS(smc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
|
||||
sPAPRCapabilityInfo *cap = &capability_table[i];
|
||||
SpaprCapabilityInfo *cap = &capability_table[i];
|
||||
const char *name = g_strdup_printf("cap-%s", cap->name);
|
||||
char *desc;
|
||||
|
||||
|
@ -28,7 +28,7 @@ static void spapr_cpu_reset(void *opaque)
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
target_ulong lpcr;
|
||||
|
||||
cpu_reset(cs);
|
||||
@ -116,7 +116,7 @@ const char *spapr_get_cpu_core_type(const char *cpu_type)
|
||||
|
||||
static bool slb_shadow_needed(void *opaque)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = opaque;
|
||||
SpaprCpuState *spapr_cpu = opaque;
|
||||
|
||||
return spapr_cpu->slb_shadow_addr != 0;
|
||||
}
|
||||
@ -127,15 +127,15 @@ static const VMStateDescription vmstate_spapr_cpu_slb_shadow = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = slb_shadow_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(slb_shadow_addr, sPAPRCPUState),
|
||||
VMSTATE_UINT64(slb_shadow_size, sPAPRCPUState),
|
||||
VMSTATE_UINT64(slb_shadow_addr, SpaprCpuState),
|
||||
VMSTATE_UINT64(slb_shadow_size, SpaprCpuState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static bool dtl_needed(void *opaque)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = opaque;
|
||||
SpaprCpuState *spapr_cpu = opaque;
|
||||
|
||||
return spapr_cpu->dtl_addr != 0;
|
||||
}
|
||||
@ -146,15 +146,15 @@ static const VMStateDescription vmstate_spapr_cpu_dtl = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = dtl_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(dtl_addr, sPAPRCPUState),
|
||||
VMSTATE_UINT64(dtl_size, sPAPRCPUState),
|
||||
VMSTATE_UINT64(dtl_addr, SpaprCpuState),
|
||||
VMSTATE_UINT64(dtl_size, SpaprCpuState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static bool vpa_needed(void *opaque)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = opaque;
|
||||
SpaprCpuState *spapr_cpu = opaque;
|
||||
|
||||
return spapr_cpu->vpa_addr != 0;
|
||||
}
|
||||
@ -165,7 +165,7 @@ static const VMStateDescription vmstate_spapr_cpu_vpa = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = vpa_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(vpa_addr, sPAPRCPUState),
|
||||
VMSTATE_UINT64(vpa_addr, SpaprCpuState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (const VMStateDescription * []) {
|
||||
@ -188,7 +188,7 @@ static const VMStateDescription vmstate_spapr_cpu_state = {
|
||||
}
|
||||
};
|
||||
|
||||
static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
|
||||
static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
|
||||
{
|
||||
if (!sc->pre_3_0_migration) {
|
||||
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
|
||||
@ -206,7 +206,7 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
|
||||
|
||||
static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
CPUCore *cc = CPU_CORE(dev);
|
||||
int i;
|
||||
|
||||
@ -216,8 +216,8 @@ static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
|
||||
g_free(sc->threads);
|
||||
}
|
||||
|
||||
static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
sPAPRCPUCore *sc, Error **errp)
|
||||
static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
SpaprCpuCore *sc, Error **errp)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -256,9 +256,9 @@ error:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int i, Error **errp)
|
||||
static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
|
||||
{
|
||||
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc);
|
||||
SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc);
|
||||
CPUCore *cc = CPU_CORE(sc);
|
||||
Object *obj;
|
||||
char *id;
|
||||
@ -285,7 +285,7 @@ static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int i, Error **errp)
|
||||
goto err;
|
||||
}
|
||||
|
||||
cpu->machine_data = g_new0(sPAPRCPUState, 1);
|
||||
cpu->machine_data = g_new0(SpaprCpuState, 1);
|
||||
|
||||
object_unref(obj);
|
||||
return cpu;
|
||||
@ -296,9 +296,9 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void spapr_delete_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
|
||||
static void spapr_delete_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
cpu->machine_data = NULL;
|
||||
g_free(spapr_cpu);
|
||||
@ -310,10 +310,10 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
|
||||
/* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
|
||||
* tries to add a sPAPR CPU core to a non-pseries machine.
|
||||
*/
|
||||
sPAPRMachineState *spapr =
|
||||
(sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(),
|
||||
SpaprMachineState *spapr =
|
||||
(SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
|
||||
TYPE_SPAPR_MACHINE);
|
||||
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
CPUCore *cc = CPU_CORE(OBJECT(dev));
|
||||
Error *local_err = NULL;
|
||||
int i, j;
|
||||
@ -352,8 +352,8 @@ err:
|
||||
}
|
||||
|
||||
static Property spapr_cpu_core_properties[] = {
|
||||
DEFINE_PROP_INT32("node-id", sPAPRCPUCore, node_id, CPU_UNSET_NUMA_NODE_ID),
|
||||
DEFINE_PROP_BOOL("pre-3.0-migration", sPAPRCPUCore, pre_3_0_migration,
|
||||
DEFINE_PROP_INT32("node-id", SpaprCpuCore, node_id, CPU_UNSET_NUMA_NODE_ID),
|
||||
DEFINE_PROP_BOOL("pre-3.0-migration", SpaprCpuCore, pre_3_0_migration,
|
||||
false),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
@ -361,7 +361,7 @@ static Property spapr_cpu_core_properties[] = {
|
||||
static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
|
||||
SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
|
||||
|
||||
dc->realize = spapr_cpu_core_realize;
|
||||
dc->unrealize = spapr_cpu_core_unrealize;
|
||||
@ -382,8 +382,8 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
|
||||
.name = TYPE_SPAPR_CPU_CORE,
|
||||
.parent = TYPE_CPU_CORE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(sPAPRCPUCore),
|
||||
.class_size = sizeof(sPAPRCPUCoreClass),
|
||||
.instance_size = sizeof(SpaprCpuCore),
|
||||
.class_size = sizeof(SpaprCpuCoreClass),
|
||||
},
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("970_v2.2"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("970mp_v1.0"),
|
||||
|
@ -29,16 +29,16 @@
|
||||
#define DRC_INDEX_TYPE_SHIFT 28
|
||||
#define DRC_INDEX_ID_MASK ((1ULL << DRC_INDEX_TYPE_SHIFT) - 1)
|
||||
|
||||
sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc)
|
||||
SpaprDrcType spapr_drc_type(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
return 1 << drck->typeshift;
|
||||
}
|
||||
|
||||
uint32_t spapr_drc_index(sPAPRDRConnector *drc)
|
||||
uint32_t spapr_drc_index(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
/* no set format for a drc index: it only needs to be globally
|
||||
* unique. this is how we encode the DRC type on bare-metal
|
||||
@ -48,7 +48,7 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
|
||||
| (drc->id & DRC_INDEX_ID_MASK);
|
||||
}
|
||||
|
||||
static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_isolate_physical(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_PHYSICAL_POWERON:
|
||||
@ -72,7 +72,7 @@ static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_unisolate_physical(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_PHYSICAL_UNISOLATE:
|
||||
@ -99,7 +99,7 @@ static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_isolate_logical(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
|
||||
@ -146,7 +146,7 @@ static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t drc_unisolate_logical(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_unisolate_logical(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
|
||||
@ -170,7 +170,7 @@ static uint32_t drc_unisolate_logical(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t drc_set_usable(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_set_usable(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
|
||||
@ -202,7 +202,7 @@ static uint32_t drc_set_usable(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
|
||||
static uint32_t drc_set_unusable(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
|
||||
@ -226,9 +226,9 @@ static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static const char *spapr_drc_name(sPAPRDRConnector *drc)
|
||||
static const char *spapr_drc_name(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
/* human-readable name for a DRC to encode into the DT
|
||||
* description. this is mainly only used within a guest in place
|
||||
@ -261,7 +261,7 @@ static const char *spapr_drc_name(sPAPRDRConnector *drc)
|
||||
* based on the current allocation/indicator/power states
|
||||
* for the DR connector.
|
||||
*/
|
||||
static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
|
||||
static SpaprDREntitySense physical_entity_sense(SpaprDrc *drc)
|
||||
{
|
||||
/* this assumes all PCI devices are assigned to a 'live insertion'
|
||||
* power domain, where QEMU manages power state automatically as
|
||||
@ -272,7 +272,7 @@ static sPAPRDREntitySense physical_entity_sense(sPAPRDRConnector *drc)
|
||||
: SPAPR_DR_ENTITY_SENSE_EMPTY;
|
||||
}
|
||||
|
||||
static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
|
||||
static SpaprDREntitySense logical_entity_sense(SpaprDrc *drc)
|
||||
{
|
||||
switch (drc->state) {
|
||||
case SPAPR_DRC_STATE_LOGICAL_UNUSABLE:
|
||||
@ -290,7 +290,7 @@ static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc)
|
||||
static void prop_get_index(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
uint32_t value = spapr_drc_index(drc);
|
||||
visit_type_uint32(v, name, &value, errp);
|
||||
}
|
||||
@ -298,7 +298,7 @@ static void prop_get_index(Object *obj, Visitor *v, const char *name,
|
||||
static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
QNull *null = NULL;
|
||||
Error *err = NULL;
|
||||
int fdt_offset_next, fdt_offset, fdt_depth;
|
||||
@ -374,7 +374,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
|
||||
} while (fdt_depth != 0);
|
||||
}
|
||||
|
||||
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
||||
void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp)
|
||||
{
|
||||
trace_spapr_drc_attach(spapr_drc_index(drc));
|
||||
|
||||
@ -393,9 +393,9 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static void spapr_drc_release(sPAPRDRConnector *drc)
|
||||
static void spapr_drc_release(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
drck->release(drc->dev);
|
||||
|
||||
@ -407,9 +407,9 @@ static void spapr_drc_release(sPAPRDRConnector *drc)
|
||||
drc->dev = NULL;
|
||||
}
|
||||
|
||||
void spapr_drc_detach(sPAPRDRConnector *drc)
|
||||
void spapr_drc_detach(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
trace_spapr_drc_detach(spapr_drc_index(drc));
|
||||
|
||||
@ -425,9 +425,9 @@ void spapr_drc_detach(sPAPRDRConnector *drc)
|
||||
spapr_drc_release(drc);
|
||||
}
|
||||
|
||||
void spapr_drc_reset(sPAPRDRConnector *drc)
|
||||
void spapr_drc_reset(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
trace_spapr_drc_reset(spapr_drc_index(drc));
|
||||
|
||||
@ -456,8 +456,8 @@ void spapr_drc_reset(sPAPRDRConnector *drc)
|
||||
|
||||
bool spapr_drc_needed(void *opaque)
|
||||
{
|
||||
sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrc *drc = (SpaprDrc *)opaque;
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
/* If no dev is plugged in there is no need to migrate the DRC state */
|
||||
if (!drc->dev) {
|
||||
@ -477,14 +477,14 @@ static const VMStateDescription vmstate_spapr_drc = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_drc_needed,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_UINT32(state, sPAPRDRConnector),
|
||||
VMSTATE_UINT32(state, SpaprDrc),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void realize(DeviceState *d, Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
|
||||
Object *root_container;
|
||||
gchar *link_name;
|
||||
gchar *child_name;
|
||||
@ -517,7 +517,7 @@ static void realize(DeviceState *d, Error **errp)
|
||||
|
||||
static void unrealize(DeviceState *d, Error **errp)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(d);
|
||||
Object *root_container;
|
||||
gchar *name;
|
||||
|
||||
@ -529,10 +529,10 @@ static void unrealize(DeviceState *d, Error **errp)
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
|
||||
SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
|
||||
uint32_t id)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(object_new(type));
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(object_new(type));
|
||||
char *prop_name;
|
||||
|
||||
drc->id = id;
|
||||
@ -549,8 +549,8 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
|
||||
|
||||
static void spapr_dr_connector_instance_init(Object *obj)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(obj);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
object_property_add_uint32_ptr(obj, "id", &drc->id, NULL);
|
||||
object_property_add(obj, "index", "uint32", prop_get_index,
|
||||
@ -574,8 +574,8 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static bool drc_physical_needed(void *opaque)
|
||||
{
|
||||
sPAPRDRCPhysical *drcp = (sPAPRDRCPhysical *)opaque;
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(drcp);
|
||||
SpaprDrcPhysical *drcp = (SpaprDrcPhysical *)opaque;
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(drcp);
|
||||
|
||||
if ((drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_ACTIVE))
|
||||
|| (!drc->dev && (drcp->dr_indicator == SPAPR_DR_INDICATOR_INACTIVE))) {
|
||||
@ -590,15 +590,15 @@ static const VMStateDescription vmstate_spapr_drc_physical = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = drc_physical_needed,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_UINT32(dr_indicator, sPAPRDRCPhysical),
|
||||
VMSTATE_UINT32(dr_indicator, SpaprDrcPhysical),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void drc_physical_reset(void *opaque)
|
||||
{
|
||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(opaque);
|
||||
sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(drc);
|
||||
SpaprDrc *drc = SPAPR_DR_CONNECTOR(opaque);
|
||||
SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(drc);
|
||||
|
||||
if (drc->dev) {
|
||||
drcp->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
|
||||
@ -609,7 +609,7 @@ static void drc_physical_reset(void *opaque)
|
||||
|
||||
static void realize_physical(DeviceState *d, Error **errp)
|
||||
{
|
||||
sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
|
||||
SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
|
||||
Error *local_err = NULL;
|
||||
|
||||
realize(d, &local_err);
|
||||
@ -625,7 +625,7 @@ static void realize_physical(DeviceState *d, Error **errp)
|
||||
|
||||
static void unrealize_physical(DeviceState *d, Error **errp)
|
||||
{
|
||||
sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
|
||||
SpaprDrcPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
|
||||
Error *local_err = NULL;
|
||||
|
||||
unrealize(d, &local_err);
|
||||
@ -641,7 +641,7 @@ static void unrealize_physical(DeviceState *d, Error **errp)
|
||||
static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
DeviceClass *dk = DEVICE_CLASS(k);
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
dk->realize = realize_physical;
|
||||
dk->unrealize = unrealize_physical;
|
||||
@ -654,7 +654,7 @@ static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->dr_entity_sense = logical_entity_sense;
|
||||
drck->isolate = drc_isolate_logical;
|
||||
@ -665,7 +665,7 @@ static void spapr_drc_logical_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
|
||||
drck->typename = "CPU";
|
||||
@ -676,7 +676,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
|
||||
drck->typename = "28";
|
||||
@ -687,7 +687,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
|
||||
drck->typename = "MEM";
|
||||
@ -698,7 +698,7 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
|
||||
|
||||
static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
|
||||
|
||||
drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PHB;
|
||||
drck->typename = "PHB";
|
||||
@ -710,9 +710,9 @@ static void spapr_drc_phb_class_init(ObjectClass *k, void *data)
|
||||
static const TypeInfo spapr_dr_connector_info = {
|
||||
.name = TYPE_SPAPR_DR_CONNECTOR,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(sPAPRDRConnector),
|
||||
.instance_size = sizeof(SpaprDrc),
|
||||
.instance_init = spapr_dr_connector_instance_init,
|
||||
.class_size = sizeof(sPAPRDRConnectorClass),
|
||||
.class_size = sizeof(SpaprDrcClass),
|
||||
.class_init = spapr_dr_connector_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
@ -720,7 +720,7 @@ static const TypeInfo spapr_dr_connector_info = {
|
||||
static const TypeInfo spapr_drc_physical_info = {
|
||||
.name = TYPE_SPAPR_DRC_PHYSICAL,
|
||||
.parent = TYPE_SPAPR_DR_CONNECTOR,
|
||||
.instance_size = sizeof(sPAPRDRCPhysical),
|
||||
.instance_size = sizeof(SpaprDrcPhysical),
|
||||
.class_init = spapr_drc_physical_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
@ -753,13 +753,13 @@ static const TypeInfo spapr_drc_lmb_info = {
|
||||
static const TypeInfo spapr_drc_phb_info = {
|
||||
.name = TYPE_SPAPR_DRC_PHB,
|
||||
.parent = TYPE_SPAPR_DRC_LOGICAL,
|
||||
.instance_size = sizeof(sPAPRDRConnector),
|
||||
.instance_size = sizeof(SpaprDrc),
|
||||
.class_init = spapr_drc_phb_class_init,
|
||||
};
|
||||
|
||||
/* helper functions for external users */
|
||||
|
||||
sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
|
||||
SpaprDrc *spapr_drc_by_index(uint32_t index)
|
||||
{
|
||||
Object *obj;
|
||||
gchar *name;
|
||||
@ -771,9 +771,9 @@ sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
|
||||
return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
|
||||
}
|
||||
|
||||
sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id)
|
||||
SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
|
||||
{
|
||||
sPAPRDRConnectorClass *drck
|
||||
SpaprDrcClass *drck
|
||||
= SPAPR_DR_CONNECTOR_CLASS(object_class_by_name(type));
|
||||
|
||||
return spapr_drc_by_index(drck->typeshift << DRC_INDEX_TYPE_SHIFT
|
||||
@ -787,7 +787,7 @@ sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id)
|
||||
* @path: path in the DT to generate properties
|
||||
* @owner: parent Object/DeviceState for which to generate DRC
|
||||
* descriptions for
|
||||
* @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
|
||||
* @drc_type_mask: mask of SpaprDrcType values corresponding
|
||||
* to the types of DRCs to generate entries for
|
||||
*
|
||||
* generate OF properties to describe DRC topology/indices to guests
|
||||
@ -826,8 +826,8 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
||||
object_property_iter_init(&iter, root_container);
|
||||
while ((prop = object_property_iter_next(&iter))) {
|
||||
Object *obj;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
SpaprDrc *drc;
|
||||
SpaprDrcClass *drck;
|
||||
uint32_t drc_index, drc_power_domain;
|
||||
|
||||
if (!strstart(prop->type, "link<", NULL)) {
|
||||
@ -918,8 +918,8 @@ out:
|
||||
|
||||
static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
sPAPRDRConnectorClass *drck;
|
||||
SpaprDrc *drc = spapr_drc_by_index(idx);
|
||||
SpaprDrcClass *drck;
|
||||
|
||||
if (!drc) {
|
||||
return RTAS_OUT_NO_SUCH_INDICATOR;
|
||||
@ -943,7 +943,7 @@ static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
|
||||
|
||||
static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
SpaprDrc *drc = spapr_drc_by_index(idx);
|
||||
|
||||
if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_LOGICAL)) {
|
||||
return RTAS_OUT_NO_SUCH_INDICATOR;
|
||||
@ -965,7 +965,7 @@ static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
|
||||
|
||||
static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_drc_by_index(idx);
|
||||
SpaprDrc *drc = spapr_drc_by_index(idx);
|
||||
|
||||
if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_PHYSICAL)) {
|
||||
return RTAS_OUT_NO_SUCH_INDICATOR;
|
||||
@ -982,7 +982,7 @@ static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_set_indicator(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -1017,7 +1017,7 @@ out:
|
||||
rtas_st(rets, 0, ret);
|
||||
}
|
||||
|
||||
static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_get_sensor_state(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
@ -1025,8 +1025,8 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
uint32_t sensor_type;
|
||||
uint32_t sensor_index;
|
||||
uint32_t sensor_state = 0;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
SpaprDrc *drc;
|
||||
SpaprDrcClass *drck;
|
||||
uint32_t ret = RTAS_OUT_SUCCESS;
|
||||
|
||||
if (nargs != 2 || nret != 2) {
|
||||
@ -1079,7 +1079,7 @@ static void configure_connector_st(target_ulong addr, target_ulong offset,
|
||||
}
|
||||
|
||||
static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
@ -1087,9 +1087,9 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
|
||||
uint64_t wa_addr;
|
||||
uint64_t wa_offset;
|
||||
uint32_t drc_index;
|
||||
sPAPRDRConnector *drc;
|
||||
sPAPRDRConnectorClass *drck;
|
||||
sPAPRDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
|
||||
SpaprDrc *drc;
|
||||
SpaprDrcClass *drck;
|
||||
SpaprDRCCResponse resp = SPAPR_DR_CC_RESPONSE_CONTINUE;
|
||||
int rc;
|
||||
|
||||
if (nargs != 2 || nret != 1) {
|
||||
|
@ -229,18 +229,18 @@ static const char * const event_names[EVENT_CLASS_MAX] = {
|
||||
[EVENT_CLASS_IO] = "ibm,io-events",
|
||||
};
|
||||
|
||||
struct sPAPREventSource {
|
||||
struct SpaprEventSource {
|
||||
int irq;
|
||||
uint32_t mask;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static sPAPREventSource *spapr_event_sources_new(void)
|
||||
static SpaprEventSource *spapr_event_sources_new(void)
|
||||
{
|
||||
return g_new0(sPAPREventSource, EVENT_CLASS_MAX);
|
||||
return g_new0(SpaprEventSource, EVENT_CLASS_MAX);
|
||||
}
|
||||
|
||||
static void spapr_event_sources_register(sPAPREventSource *event_sources,
|
||||
static void spapr_event_sources_register(SpaprEventSource *event_sources,
|
||||
EventClassIndex index, int irq)
|
||||
{
|
||||
/* we only support 1 irq per event class at the moment */
|
||||
@ -251,8 +251,8 @@ static void spapr_event_sources_register(sPAPREventSource *event_sources,
|
||||
event_sources[index].enabled = true;
|
||||
}
|
||||
|
||||
static const sPAPREventSource *
|
||||
spapr_event_sources_get_source(sPAPREventSource *event_sources,
|
||||
static const SpaprEventSource *
|
||||
spapr_event_sources_get_source(SpaprEventSource *event_sources,
|
||||
EventClassIndex index)
|
||||
{
|
||||
g_assert(index < EVENT_CLASS_MAX);
|
||||
@ -261,11 +261,11 @@ spapr_event_sources_get_source(sPAPREventSource *event_sources,
|
||||
return &event_sources[index];
|
||||
}
|
||||
|
||||
void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
|
||||
void spapr_dt_events(SpaprMachineState *spapr, void *fdt)
|
||||
{
|
||||
uint32_t irq_ranges[EVENT_CLASS_MAX * 2];
|
||||
int i, count = 0, event_sources;
|
||||
sPAPREventSource *events = spapr->event_sources;
|
||||
SpaprEventSource *events = spapr->event_sources;
|
||||
|
||||
g_assert(events);
|
||||
|
||||
@ -274,7 +274,7 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
|
||||
for (i = 0, count = 0; i < EVENT_CLASS_MAX; i++) {
|
||||
int node_offset;
|
||||
uint32_t interrupts[2];
|
||||
const sPAPREventSource *source =
|
||||
const SpaprEventSource *source =
|
||||
spapr_event_sources_get_source(events, i);
|
||||
const char *source_name = event_names[i];
|
||||
|
||||
@ -298,10 +298,10 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt)
|
||||
irq_ranges, count * sizeof(uint32_t))));
|
||||
}
|
||||
|
||||
static const sPAPREventSource *
|
||||
rtas_event_log_to_source(sPAPRMachineState *spapr, int log_type)
|
||||
static const SpaprEventSource *
|
||||
rtas_event_log_to_source(SpaprMachineState *spapr, int log_type)
|
||||
{
|
||||
const sPAPREventSource *source;
|
||||
const SpaprEventSource *source;
|
||||
|
||||
g_assert(spapr->event_sources);
|
||||
|
||||
@ -325,9 +325,9 @@ rtas_event_log_to_source(sPAPRMachineState *spapr, int log_type)
|
||||
return source;
|
||||
}
|
||||
|
||||
static int rtas_event_log_to_irq(sPAPRMachineState *spapr, int log_type)
|
||||
static int rtas_event_log_to_irq(SpaprMachineState *spapr, int log_type)
|
||||
{
|
||||
const sPAPREventSource *source;
|
||||
const SpaprEventSource *source;
|
||||
|
||||
source = rtas_event_log_to_source(spapr, log_type);
|
||||
g_assert(source);
|
||||
@ -336,24 +336,24 @@ static int rtas_event_log_to_irq(sPAPRMachineState *spapr, int log_type)
|
||||
return source->irq;
|
||||
}
|
||||
|
||||
static uint32_t spapr_event_log_entry_type(sPAPREventLogEntry *entry)
|
||||
static uint32_t spapr_event_log_entry_type(SpaprEventLogEntry *entry)
|
||||
{
|
||||
return entry->summary & RTAS_LOG_TYPE_MASK;
|
||||
}
|
||||
|
||||
static void rtas_event_log_queue(sPAPRMachineState *spapr,
|
||||
sPAPREventLogEntry *entry)
|
||||
static void rtas_event_log_queue(SpaprMachineState *spapr,
|
||||
SpaprEventLogEntry *entry)
|
||||
{
|
||||
QTAILQ_INSERT_TAIL(&spapr->pending_events, entry, next);
|
||||
}
|
||||
|
||||
static sPAPREventLogEntry *rtas_event_log_dequeue(sPAPRMachineState *spapr,
|
||||
static SpaprEventLogEntry *rtas_event_log_dequeue(SpaprMachineState *spapr,
|
||||
uint32_t event_mask)
|
||||
{
|
||||
sPAPREventLogEntry *entry = NULL;
|
||||
SpaprEventLogEntry *entry = NULL;
|
||||
|
||||
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
|
||||
const sPAPREventSource *source =
|
||||
const SpaprEventSource *source =
|
||||
rtas_event_log_to_source(spapr,
|
||||
spapr_event_log_entry_type(entry));
|
||||
|
||||
@ -371,11 +371,11 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(sPAPRMachineState *spapr,
|
||||
|
||||
static bool rtas_event_log_contains(uint32_t event_mask)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
sPAPREventLogEntry *entry = NULL;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprEventLogEntry *entry = NULL;
|
||||
|
||||
QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
|
||||
const sPAPREventSource *source =
|
||||
const SpaprEventSource *source =
|
||||
rtas_event_log_to_source(spapr,
|
||||
spapr_event_log_entry_type(entry));
|
||||
|
||||
@ -401,7 +401,7 @@ static void spapr_init_v6hdr(struct rtas_event_log_v6 *v6hdr)
|
||||
static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
|
||||
int section_count)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
struct tm tm;
|
||||
int year;
|
||||
|
||||
@ -424,15 +424,15 @@ static void spapr_init_maina(struct rtas_event_log_v6_maina *maina,
|
||||
|
||||
static void spapr_powerdown_req(Notifier *n, void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
sPAPREventLogEntry *entry;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprEventLogEntry *entry;
|
||||
struct rtas_event_log_v6 *v6hdr;
|
||||
struct rtas_event_log_v6_maina *maina;
|
||||
struct rtas_event_log_v6_mainb *mainb;
|
||||
struct rtas_event_log_v6_epow *epow;
|
||||
struct epow_extended_log *new_epow;
|
||||
|
||||
entry = g_new(sPAPREventLogEntry, 1);
|
||||
entry = g_new(SpaprEventLogEntry, 1);
|
||||
new_epow = g_malloc0(sizeof(*new_epow));
|
||||
entry->extended_log = new_epow;
|
||||
|
||||
@ -473,18 +473,18 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
|
||||
}
|
||||
|
||||
static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
|
||||
sPAPRDRConnectorType drc_type,
|
||||
SpaprDrcType drc_type,
|
||||
union drc_identifier *drc_id)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
sPAPREventLogEntry *entry;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprEventLogEntry *entry;
|
||||
struct hp_extended_log *new_hp;
|
||||
struct rtas_event_log_v6 *v6hdr;
|
||||
struct rtas_event_log_v6_maina *maina;
|
||||
struct rtas_event_log_v6_mainb *mainb;
|
||||
struct rtas_event_log_v6_hp *hp;
|
||||
|
||||
entry = g_new(sPAPREventLogEntry, 1);
|
||||
entry = g_new(SpaprEventLogEntry, 1);
|
||||
new_hp = g_malloc0(sizeof(struct hp_extended_log));
|
||||
entry->extended_log = new_hp;
|
||||
|
||||
@ -558,9 +558,9 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
|
||||
rtas_event_log_to_irq(spapr, RTAS_LOG_TYPE_HOTPLUG)));
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
|
||||
void spapr_hotplug_req_add_by_index(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorType drc_type = spapr_drc_type(drc);
|
||||
SpaprDrcType drc_type = spapr_drc_type(drc);
|
||||
union drc_identifier drc_id;
|
||||
|
||||
drc_id.index = spapr_drc_index(drc);
|
||||
@ -568,9 +568,9 @@ void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc)
|
||||
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc)
|
||||
void spapr_hotplug_req_remove_by_index(SpaprDrc *drc)
|
||||
{
|
||||
sPAPRDRConnectorType drc_type = spapr_drc_type(drc);
|
||||
SpaprDrcType drc_type = spapr_drc_type(drc);
|
||||
union drc_identifier drc_id;
|
||||
|
||||
drc_id.index = spapr_drc_index(drc);
|
||||
@ -578,7 +578,7 @@ void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc)
|
||||
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_add_by_count(SpaprDrcType drc_type,
|
||||
uint32_t count)
|
||||
{
|
||||
union drc_identifier drc_id;
|
||||
@ -588,7 +588,7 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
|
||||
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_remove_by_count(SpaprDrcType drc_type,
|
||||
uint32_t count)
|
||||
{
|
||||
union drc_identifier drc_id;
|
||||
@ -598,7 +598,7 @@ void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
|
||||
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_add_by_count_indexed(SpaprDrcType drc_type,
|
||||
uint32_t count, uint32_t index)
|
||||
{
|
||||
union drc_identifier drc_id;
|
||||
@ -609,7 +609,7 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
|
||||
uint32_t count, uint32_t index)
|
||||
{
|
||||
union drc_identifier drc_id;
|
||||
@ -620,14 +620,14 @@ void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id);
|
||||
}
|
||||
|
||||
static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void check_exception(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
uint32_t mask, buf, len, event_len;
|
||||
uint64_t xinfo;
|
||||
sPAPREventLogEntry *event;
|
||||
SpaprEventLogEntry *event;
|
||||
struct rtas_error_log header;
|
||||
int i;
|
||||
|
||||
@ -671,7 +671,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
*/
|
||||
for (i = 0; i < EVENT_CLASS_MAX; i++) {
|
||||
if (rtas_event_log_contains(EVENT_CLASS_MASK(i))) {
|
||||
const sPAPREventSource *source =
|
||||
const SpaprEventSource *source =
|
||||
spapr_event_sources_get_source(spapr->event_sources, i);
|
||||
|
||||
g_assert(source->enabled);
|
||||
@ -685,7 +685,7 @@ out_no_events:
|
||||
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
|
||||
}
|
||||
|
||||
static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void event_scan(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -697,9 +697,9 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
|
||||
}
|
||||
|
||||
void spapr_clear_pending_events(sPAPRMachineState *spapr)
|
||||
void spapr_clear_pending_events(SpaprMachineState *spapr)
|
||||
{
|
||||
sPAPREventLogEntry *entry = NULL, *next_entry;
|
||||
SpaprEventLogEntry *entry = NULL, *next_entry;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(entry, &spapr->pending_events, next, next_entry) {
|
||||
QTAILQ_REMOVE(&spapr->pending_events, entry, next);
|
||||
@ -708,7 +708,7 @@ void spapr_clear_pending_events(sPAPRMachineState *spapr)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_events_init(sPAPRMachineState *spapr)
|
||||
void spapr_events_init(SpaprMachineState *spapr)
|
||||
{
|
||||
int epow_irq = SPAPR_IRQ_EPOW;
|
||||
|
||||
|
@ -34,7 +34,7 @@ static inline bool valid_ptex(PowerPCCPU *cpu, target_ulong ptex)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_ram_address(sPAPRMachineState *spapr, hwaddr addr)
|
||||
static bool is_ram_address(SpaprMachineState *spapr, hwaddr addr)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
DeviceMemoryState *dms = machine->device_memory;
|
||||
@ -50,7 +50,7 @@ static bool is_ram_address(sPAPRMachineState *spapr, hwaddr addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_enter(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
@ -160,7 +160,7 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
|
||||
return REMOVE_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_remove(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -208,7 +208,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
||||
#define H_BULK_REMOVE_MAX_BATCH 4
|
||||
|
||||
static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_bulk_remove(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -260,7 +260,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_protect(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -299,7 +299,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_read(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
@ -328,7 +328,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
struct sPAPRPendingHPT {
|
||||
struct SpaprPendingHpt {
|
||||
/* These fields are read-only after initialization */
|
||||
int shift;
|
||||
QemuThread thread;
|
||||
@ -342,7 +342,7 @@ struct sPAPRPendingHPT {
|
||||
void *hpt;
|
||||
};
|
||||
|
||||
static void free_pending_hpt(sPAPRPendingHPT *pending)
|
||||
static void free_pending_hpt(SpaprPendingHpt *pending)
|
||||
{
|
||||
if (pending->hpt) {
|
||||
qemu_vfree(pending->hpt);
|
||||
@ -353,7 +353,7 @@ static void free_pending_hpt(sPAPRPendingHPT *pending)
|
||||
|
||||
static void *hpt_prepare_thread(void *opaque)
|
||||
{
|
||||
sPAPRPendingHPT *pending = opaque;
|
||||
SpaprPendingHpt *pending = opaque;
|
||||
size_t size = 1ULL << pending->shift;
|
||||
|
||||
pending->hpt = qemu_memalign(size, size);
|
||||
@ -379,9 +379,9 @@ static void *hpt_prepare_thread(void *opaque)
|
||||
}
|
||||
|
||||
/* Must be called with BQL held */
|
||||
static void cancel_hpt_prepare(sPAPRMachineState *spapr)
|
||||
static void cancel_hpt_prepare(SpaprMachineState *spapr)
|
||||
{
|
||||
sPAPRPendingHPT *pending = spapr->pending_hpt;
|
||||
SpaprPendingHpt *pending = spapr->pending_hpt;
|
||||
|
||||
/* Let the thread know it's cancelled */
|
||||
spapr->pending_hpt = NULL;
|
||||
@ -438,13 +438,13 @@ static target_ulong resize_hpt_convert_rc(int ret)
|
||||
}
|
||||
|
||||
static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
int shift = args[1];
|
||||
sPAPRPendingHPT *pending = spapr->pending_hpt;
|
||||
SpaprPendingHpt *pending = spapr->pending_hpt;
|
||||
uint64_t current_ram_size;
|
||||
int rc;
|
||||
|
||||
@ -503,7 +503,7 @@ static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu,
|
||||
|
||||
/* start new prepare */
|
||||
|
||||
pending = g_new0(sPAPRPendingHPT, 1);
|
||||
pending = g_new0(SpaprPendingHpt, 1);
|
||||
pending->shift = shift;
|
||||
pending->ret = H_HARDWARE;
|
||||
|
||||
@ -672,7 +672,7 @@ static void do_push_sregs_to_kvm_pr(CPUState *cs, run_on_cpu_data data)
|
||||
}
|
||||
}
|
||||
|
||||
static void push_sregs_to_kvm_pr(sPAPRMachineState *spapr)
|
||||
static void push_sregs_to_kvm_pr(SpaprMachineState *spapr)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
@ -691,13 +691,13 @@ static void push_sregs_to_kvm_pr(sPAPRMachineState *spapr)
|
||||
}
|
||||
|
||||
static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
target_ulong shift = args[1];
|
||||
sPAPRPendingHPT *pending = spapr->pending_hpt;
|
||||
SpaprPendingHpt *pending = spapr->pending_hpt;
|
||||
int rc;
|
||||
size_t newsize;
|
||||
|
||||
@ -759,7 +759,7 @@ static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_set_sprg0(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
cpu_synchronize_state(CPU(cpu));
|
||||
@ -768,7 +768,7 @@ static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_set_dabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
if (!has_spr(cpu, SPR_DABR)) {
|
||||
@ -786,7 +786,7 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_set_xdabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_set_xdabr(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong dabrx = args[1];
|
||||
@ -807,7 +807,7 @@ static target_ulong h_set_xdabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_page_init(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
@ -882,7 +882,7 @@ static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
uint16_t size;
|
||||
uint8_t tmp;
|
||||
|
||||
@ -918,7 +918,7 @@ static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa)
|
||||
|
||||
static target_ulong deregister_vpa(PowerPCCPU *cpu, target_ulong vpa)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
if (spapr_cpu->slb_shadow_addr) {
|
||||
return H_RESOURCE;
|
||||
@ -934,7 +934,7 @@ static target_ulong deregister_vpa(PowerPCCPU *cpu, target_ulong vpa)
|
||||
|
||||
static target_ulong register_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
uint32_t size;
|
||||
|
||||
if (addr == 0) {
|
||||
@ -963,7 +963,7 @@ static target_ulong register_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
|
||||
|
||||
static target_ulong deregister_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
spapr_cpu->slb_shadow_addr = 0;
|
||||
spapr_cpu->slb_shadow_size = 0;
|
||||
@ -972,7 +972,7 @@ static target_ulong deregister_slb_shadow(PowerPCCPU *cpu, target_ulong addr)
|
||||
|
||||
static target_ulong register_dtl(PowerPCCPU *cpu, target_ulong addr)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
uint32_t size;
|
||||
|
||||
if (addr == 0) {
|
||||
@ -998,7 +998,7 @@ static target_ulong register_dtl(PowerPCCPU *cpu, target_ulong addr)
|
||||
|
||||
static target_ulong deregister_dtl(PowerPCCPU *cpu, target_ulong addr)
|
||||
{
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
spapr_cpu->dtl_addr = 0;
|
||||
spapr_cpu->dtl_size = 0;
|
||||
@ -1006,7 +1006,7 @@ static target_ulong deregister_dtl(PowerPCCPU *cpu, target_ulong addr)
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_register_vpa(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong flags = args[0];
|
||||
@ -1049,7 +1049,7 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
@ -1065,7 +1065,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_rtas(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong rtas_r3 = args[0];
|
||||
@ -1077,7 +1077,7 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
nret, rtas_r3 + 12 + 4*nargs);
|
||||
}
|
||||
|
||||
static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_logical_load(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -1101,7 +1101,7 @@ static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_logical_store(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -1127,7 +1127,7 @@ static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_logical_memop(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -1196,14 +1196,14 @@ static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_logical_icbi(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
/* Nothing to do on emulation, KVM will trap this in the kernel */
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_logical_dcbf(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
/* Nothing to do on emulation, KVM will trap this in the kernel */
|
||||
@ -1263,7 +1263,7 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong resource = args[1];
|
||||
@ -1282,7 +1282,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static target_ulong h_clean_slb(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_clean_slb(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
|
||||
@ -1290,7 +1290,7 @@ static target_ulong h_clean_slb(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_FUNCTION;
|
||||
}
|
||||
|
||||
static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_invalidate_pid(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",
|
||||
@ -1298,7 +1298,7 @@ static target_ulong h_invalidate_pid(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_FUNCTION;
|
||||
}
|
||||
|
||||
static void spapr_check_setup_free_hpt(sPAPRMachineState *spapr,
|
||||
static void spapr_check_setup_free_hpt(SpaprMachineState *spapr,
|
||||
uint64_t patbe_old, uint64_t patbe_new)
|
||||
{
|
||||
/*
|
||||
@ -1331,7 +1331,7 @@ static void spapr_check_setup_free_hpt(sPAPRMachineState *spapr,
|
||||
#define FLAG_GTSE 0x01
|
||||
|
||||
static target_ulong h_register_process_table(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1339,6 +1339,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
|
||||
target_ulong proc_tbl = args[1];
|
||||
target_ulong page_size = args[2];
|
||||
target_ulong table_size = args[3];
|
||||
target_ulong update_lpcr = 0;
|
||||
uint64_t cproc;
|
||||
|
||||
if (flags & ~FLAGS_MASK) { /* Check no reserved bits are set */
|
||||
@ -1394,10 +1395,13 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
|
||||
spapr->patb_entry = cproc; /* Save new process table */
|
||||
|
||||
/* Update the UPRT, HR and GTSE bits in the LPCR for all cpus */
|
||||
spapr_set_all_lpcrs(((flags & (FLAG_RADIX | FLAG_HASH_PROC_TBL)) ?
|
||||
(LPCR_UPRT | LPCR_HR) : 0) |
|
||||
((flags & FLAG_GTSE) ? LPCR_GTSE : 0),
|
||||
LPCR_UPRT | LPCR_HR | LPCR_GTSE);
|
||||
if (flags & FLAG_RADIX) /* Radix must use process tables, also set HR */
|
||||
update_lpcr |= (LPCR_UPRT | LPCR_HR);
|
||||
else if (flags & FLAG_HASH_PROC_TBL) /* Hash with process tables */
|
||||
update_lpcr |= LPCR_UPRT;
|
||||
if (flags & FLAG_GTSE) /* Guest translation shootdown enable */
|
||||
update_lpcr |= FLAG_GTSE;
|
||||
spapr_set_all_lpcrs(update_lpcr, LPCR_UPRT | LPCR_HR | LPCR_GTSE);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
return kvmppc_configure_v3_mmu(cpu, flags & FLAG_RADIX,
|
||||
@ -1410,7 +1414,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu,
|
||||
#define H_SIGNAL_SYS_RESET_ALLBUTSELF -2
|
||||
|
||||
static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_long target = args[0];
|
||||
@ -1445,7 +1449,7 @@ static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
||||
static uint32_t cas_check_pvr(SpaprMachineState *spapr, PowerPCCPU *cpu,
|
||||
target_ulong *addr, bool *raw_mode_supported,
|
||||
Error **errp)
|
||||
{
|
||||
@ -1496,7 +1500,7 @@ static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1504,7 +1508,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
target_ulong addr = ppc64_phys_to_real(args[0]);
|
||||
target_ulong ov_table;
|
||||
uint32_t cas_pvr;
|
||||
sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
|
||||
SpaprOptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
|
||||
bool guest_radix;
|
||||
Error *local_err = NULL;
|
||||
bool raw_mode_supported = false;
|
||||
@ -1647,7 +1651,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1683,7 +1687,7 @@ static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
@ -1693,6 +1697,8 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
||||
uint8_t safe_cache = spapr_get_cap(spapr, SPAPR_CAP_CFPC);
|
||||
uint8_t safe_bounds_check = spapr_get_cap(spapr, SPAPR_CAP_SBBC);
|
||||
uint8_t safe_indirect_branch = spapr_get_cap(spapr, SPAPR_CAP_IBS);
|
||||
uint8_t count_cache_flush_assist = spapr_get_cap(spapr,
|
||||
SPAPR_CAP_CCF_ASSIST);
|
||||
|
||||
switch (safe_cache) {
|
||||
case SPAPR_CAP_WORKAROUND:
|
||||
@ -1723,12 +1729,20 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
switch (safe_indirect_branch) {
|
||||
case SPAPR_CAP_FIXED_NA:
|
||||
break;
|
||||
case SPAPR_CAP_FIXED_CCD:
|
||||
characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
|
||||
break;
|
||||
case SPAPR_CAP_FIXED_IBS:
|
||||
characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
|
||||
break;
|
||||
case SPAPR_CAP_WORKAROUND:
|
||||
behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
|
||||
if (count_cache_flush_assist) {
|
||||
characteristics |= H_CPU_CHAR_BCCTR_FLUSH_ASSIST;
|
||||
}
|
||||
break;
|
||||
default: /* broken */
|
||||
assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
|
||||
break;
|
||||
@ -1739,13 +1753,13 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_update_dt(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong dt = ppc64_phys_to_real(args[0]);
|
||||
struct fdt_header hdr = { 0 };
|
||||
unsigned cb;
|
||||
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
void *fdt;
|
||||
|
||||
cpu_physical_memory_read(dt, &hdr, sizeof(hdr));
|
||||
@ -1804,7 +1818,7 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
|
||||
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
|
||||
if ((opcode <= MAX_HCALL_OPCODE)
|
||||
&& ((opcode & 0x3) == 0)) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
enum sPAPRTCEAccess {
|
||||
enum SpaprTceAccess {
|
||||
SPAPR_TCE_FAULT = 0,
|
||||
SPAPR_TCE_RO = 1,
|
||||
SPAPR_TCE_WO = 2,
|
||||
@ -42,11 +42,11 @@ enum sPAPRTCEAccess {
|
||||
#define IOMMU_PAGE_SIZE(shift) (1ULL << (shift))
|
||||
#define IOMMU_PAGE_MASK(shift) (~(IOMMU_PAGE_SIZE(shift) - 1))
|
||||
|
||||
static QLIST_HEAD(, sPAPRTCETable) spapr_tce_tables;
|
||||
static QLIST_HEAD(, SpaprTceTable) spapr_tce_tables;
|
||||
|
||||
sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn)
|
||||
SpaprTceTable *spapr_tce_find_by_liobn(target_ulong liobn)
|
||||
{
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
|
||||
if (liobn & 0xFFFFFFFF00000000ULL) {
|
||||
hcall_dprintf("Request for out-of-bounds LIOBN 0x" TARGET_FMT_lx "\n",
|
||||
@ -115,7 +115,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
|
||||
IOMMUAccessFlags flag,
|
||||
int iommu_idx)
|
||||
{
|
||||
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
|
||||
SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
|
||||
uint64_t tce;
|
||||
IOMMUTLBEntry ret = {
|
||||
.target_as = &address_space_memory,
|
||||
@ -141,9 +141,39 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spapr_tce_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
|
||||
{
|
||||
MemoryRegion *mr = MEMORY_REGION(iommu_mr);
|
||||
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
|
||||
hwaddr addr, granularity;
|
||||
IOMMUTLBEntry iotlb;
|
||||
SpaprTceTable *tcet = container_of(iommu_mr, SpaprTceTable, iommu);
|
||||
|
||||
if (tcet->skipping_replay) {
|
||||
return;
|
||||
}
|
||||
|
||||
granularity = memory_region_iommu_get_min_page_size(iommu_mr);
|
||||
|
||||
for (addr = 0; addr < memory_region_size(mr); addr += granularity) {
|
||||
iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, n->iommu_idx);
|
||||
if (iotlb.perm != IOMMU_NONE) {
|
||||
n->notify(n, &iotlb);
|
||||
}
|
||||
|
||||
/*
|
||||
* if (2^64 - MR size) < granularity, it's possible to get an
|
||||
* infinite loop here. This should catch such a wraparound.
|
||||
*/
|
||||
if ((addr + granularity) < addr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int spapr_tce_table_pre_save(void *opaque)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
|
||||
SpaprTceTable *tcet = SPAPR_TCE_TABLE(opaque);
|
||||
|
||||
tcet->mig_table = tcet->table;
|
||||
tcet->mig_nb_table = tcet->nb_table;
|
||||
@ -156,7 +186,7 @@ static int spapr_tce_table_pre_save(void *opaque)
|
||||
|
||||
static uint64_t spapr_tce_get_min_page_size(IOMMUMemoryRegion *iommu)
|
||||
{
|
||||
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
|
||||
SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
|
||||
|
||||
return 1ULL << tcet->page_shift;
|
||||
}
|
||||
@ -164,7 +194,7 @@ static uint64_t spapr_tce_get_min_page_size(IOMMUMemoryRegion *iommu)
|
||||
static int spapr_tce_get_attr(IOMMUMemoryRegion *iommu,
|
||||
enum IOMMUMemoryRegionAttr attr, void *data)
|
||||
{
|
||||
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
|
||||
SpaprTceTable *tcet = container_of(iommu, SpaprTceTable, iommu);
|
||||
|
||||
if (attr == IOMMU_ATTR_SPAPR_TCE_FD && kvmppc_has_cap_spapr_vfio()) {
|
||||
*(int *) data = tcet->fd;
|
||||
@ -178,7 +208,7 @@ static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
IOMMUNotifierFlag old,
|
||||
IOMMUNotifierFlag new)
|
||||
{
|
||||
struct sPAPRTCETable *tbl = container_of(iommu, sPAPRTCETable, iommu);
|
||||
struct SpaprTceTable *tbl = container_of(iommu, SpaprTceTable, iommu);
|
||||
|
||||
if (old == IOMMU_NOTIFIER_NONE && new != IOMMU_NOTIFIER_NONE) {
|
||||
spapr_tce_set_need_vfio(tbl, true);
|
||||
@ -189,7 +219,7 @@ static void spapr_tce_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
|
||||
static int spapr_tce_table_post_load(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
|
||||
SpaprTceTable *tcet = SPAPR_TCE_TABLE(opaque);
|
||||
uint32_t old_nb_table = tcet->nb_table;
|
||||
uint64_t old_bus_offset = tcet->bus_offset;
|
||||
uint32_t old_page_shift = tcet->page_shift;
|
||||
@ -223,7 +253,7 @@ static int spapr_tce_table_post_load(void *opaque, int version_id)
|
||||
|
||||
static bool spapr_tce_table_ex_needed(void *opaque)
|
||||
{
|
||||
sPAPRTCETable *tcet = opaque;
|
||||
SpaprTceTable *tcet = opaque;
|
||||
|
||||
return tcet->bus_offset || tcet->page_shift != 0xC;
|
||||
}
|
||||
@ -234,8 +264,8 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = {
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_tce_table_ex_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(bus_offset, sPAPRTCETable),
|
||||
VMSTATE_UINT32(page_shift, sPAPRTCETable),
|
||||
VMSTATE_UINT64(bus_offset, SpaprTceTable),
|
||||
VMSTATE_UINT32(page_shift, SpaprTceTable),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
@ -248,12 +278,12 @@ static const VMStateDescription vmstate_spapr_tce_table = {
|
||||
.post_load = spapr_tce_table_post_load,
|
||||
.fields = (VMStateField []) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable, NULL),
|
||||
VMSTATE_UINT32_EQUAL(liobn, SpaprTceTable, NULL),
|
||||
|
||||
/* IOMMU state */
|
||||
VMSTATE_UINT32(mig_nb_table, sPAPRTCETable),
|
||||
VMSTATE_BOOL(bypass, sPAPRTCETable),
|
||||
VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, mig_nb_table, 0,
|
||||
VMSTATE_UINT32(mig_nb_table, SpaprTceTable),
|
||||
VMSTATE_BOOL(bypass, SpaprTceTable),
|
||||
VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0,
|
||||
vmstate_info_uint64, uint64_t),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
@ -266,7 +296,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
|
||||
|
||||
static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
Object *tcetobj = OBJECT(tcet);
|
||||
gchar *tmp;
|
||||
|
||||
@ -288,7 +318,7 @@ static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
|
||||
tcet);
|
||||
}
|
||||
|
||||
void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
|
||||
void spapr_tce_set_need_vfio(SpaprTceTable *tcet, bool need_vfio)
|
||||
{
|
||||
size_t table_size = tcet->nb_table * sizeof(uint64_t);
|
||||
uint64_t *oldtable;
|
||||
@ -317,9 +347,9 @@ void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
|
||||
tcet->fd = newfd;
|
||||
}
|
||||
|
||||
sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
|
||||
SpaprTceTable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
|
||||
{
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
gchar *tmp;
|
||||
|
||||
if (spapr_tce_find_by_liobn(liobn)) {
|
||||
@ -341,7 +371,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
|
||||
return tcet;
|
||||
}
|
||||
|
||||
void spapr_tce_table_enable(sPAPRTCETable *tcet,
|
||||
void spapr_tce_table_enable(SpaprTceTable *tcet,
|
||||
uint32_t page_shift, uint64_t bus_offset,
|
||||
uint32_t nb_table)
|
||||
{
|
||||
@ -366,7 +396,7 @@ void spapr_tce_table_enable(sPAPRTCETable *tcet,
|
||||
MEMORY_REGION(&tcet->iommu));
|
||||
}
|
||||
|
||||
void spapr_tce_table_disable(sPAPRTCETable *tcet)
|
||||
void spapr_tce_table_disable(SpaprTceTable *tcet)
|
||||
{
|
||||
if (!tcet->nb_table) {
|
||||
return;
|
||||
@ -385,7 +415,7 @@ void spapr_tce_table_disable(sPAPRTCETable *tcet)
|
||||
|
||||
static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
|
||||
vmstate_unregister(DEVICE(tcet), &vmstate_spapr_tce_table, tcet);
|
||||
|
||||
@ -394,14 +424,14 @@ static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
|
||||
spapr_tce_table_disable(tcet);
|
||||
}
|
||||
|
||||
MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet)
|
||||
MemoryRegion *spapr_tce_get_iommu(SpaprTceTable *tcet)
|
||||
{
|
||||
return &tcet->root;
|
||||
}
|
||||
|
||||
static void spapr_tce_reset(DeviceState *dev)
|
||||
{
|
||||
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
SpaprTceTable *tcet = SPAPR_TCE_TABLE(dev);
|
||||
size_t table_size = tcet->nb_table * sizeof(uint64_t);
|
||||
|
||||
if (tcet->nb_table) {
|
||||
@ -409,7 +439,7 @@ static void spapr_tce_reset(DeviceState *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
|
||||
static target_ulong put_tce_emu(SpaprTceTable *tcet, target_ulong ioba,
|
||||
target_ulong tce)
|
||||
{
|
||||
IOMMUTLBEntry entry;
|
||||
@ -435,7 +465,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
|
||||
}
|
||||
|
||||
static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
int i;
|
||||
@ -445,7 +475,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
|
||||
target_ulong tce_list = args[2];
|
||||
target_ulong npages = args[3];
|
||||
target_ulong ret = H_PARAMETER, tce = 0;
|
||||
sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
CPUState *cs = CPU(cpu);
|
||||
hwaddr page_mask, page_size;
|
||||
|
||||
@ -480,7 +510,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_stuff_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
int i;
|
||||
@ -489,7 +519,7 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
target_ulong tce_value = args[2];
|
||||
target_ulong npages = args[3];
|
||||
target_ulong ret = H_PARAMETER;
|
||||
sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
hwaddr page_mask, page_size;
|
||||
|
||||
if (!tcet) {
|
||||
@ -519,14 +549,14 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_put_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong liobn = args[0];
|
||||
target_ulong ioba = args[1];
|
||||
target_ulong tce = args[2];
|
||||
target_ulong ret = H_PARAMETER;
|
||||
sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
|
||||
if (tcet) {
|
||||
hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift);
|
||||
@ -544,7 +574,7 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
|
||||
static target_ulong get_tce_emu(SpaprTceTable *tcet, target_ulong ioba,
|
||||
target_ulong *tce)
|
||||
{
|
||||
unsigned long index = (ioba - tcet->bus_offset) >> tcet->page_shift;
|
||||
@ -560,14 +590,14 @@ static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_get_tce(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong liobn = args[0];
|
||||
target_ulong ioba = args[1];
|
||||
target_ulong tce = 0;
|
||||
target_ulong ret = H_PARAMETER;
|
||||
sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
SpaprTceTable *tcet = spapr_tce_find_by_liobn(liobn);
|
||||
|
||||
if (tcet) {
|
||||
hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift);
|
||||
@ -619,7 +649,7 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
|
||||
}
|
||||
|
||||
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
|
||||
sPAPRTCETable *tcet)
|
||||
SpaprTceTable *tcet)
|
||||
{
|
||||
if (!tcet) {
|
||||
return 0;
|
||||
@ -650,7 +680,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
|
||||
static TypeInfo spapr_tce_table_info = {
|
||||
.name = TYPE_SPAPR_TCE_TABLE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(sPAPRTCETable),
|
||||
.instance_size = sizeof(SpaprTceTable),
|
||||
.class_init = spapr_tce_table_class_init,
|
||||
};
|
||||
|
||||
@ -659,6 +689,7 @@ static void spapr_iommu_memory_region_class_init(ObjectClass *klass, void *data)
|
||||
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
|
||||
|
||||
imrc->translate = spapr_tce_translate_iommu;
|
||||
imrc->replay = spapr_tce_replay;
|
||||
imrc->get_min_page_size = spapr_tce_get_min_page_size;
|
||||
imrc->notify_flag_changed = spapr_tce_notify_flag_changed;
|
||||
imrc->get_attr = spapr_tce_get_attr;
|
||||
|
@ -20,13 +20,13 @@
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis)
|
||||
void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis)
|
||||
{
|
||||
spapr->irq_map_nr = nr_msis;
|
||||
spapr->irq_map = bitmap_new(spapr->irq_map_nr);
|
||||
}
|
||||
|
||||
int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
|
||||
int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
|
||||
Error **errp)
|
||||
{
|
||||
int irq;
|
||||
@ -51,12 +51,12 @@ int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
|
||||
return irq + SPAPR_IRQ_MSI;
|
||||
}
|
||||
|
||||
void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num)
|
||||
void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num)
|
||||
{
|
||||
bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num);
|
||||
}
|
||||
|
||||
void spapr_irq_msi_reset(sPAPRMachineState *spapr)
|
||||
void spapr_irq_msi_reset(SpaprMachineState *spapr)
|
||||
{
|
||||
bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr);
|
||||
}
|
||||
@ -66,7 +66,7 @@ void spapr_irq_msi_reset(sPAPRMachineState *spapr)
|
||||
* XICS IRQ backend.
|
||||
*/
|
||||
|
||||
static ICSState *spapr_ics_create(sPAPRMachineState *spapr,
|
||||
static ICSState *spapr_ics_create(SpaprMachineState *spapr,
|
||||
int nr_irqs, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
@ -92,7 +92,7 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs,
|
||||
static void spapr_irq_init_xics(SpaprMachineState *spapr, int nr_irqs,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
@ -126,7 +126,7 @@ error:
|
||||
#define ICS_IRQ_FREE(ics, srcno) \
|
||||
(!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK)))
|
||||
|
||||
static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
static int spapr_irq_claim_xics(SpaprMachineState *spapr, int irq, bool lsi,
|
||||
Error **errp)
|
||||
{
|
||||
ICSState *ics = spapr->ics;
|
||||
@ -147,7 +147,7 @@ static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num)
|
||||
static void spapr_irq_free_xics(SpaprMachineState *spapr, int irq, int num)
|
||||
{
|
||||
ICSState *ics = spapr->ics;
|
||||
uint32_t srcno = irq - ics->offset;
|
||||
@ -164,7 +164,7 @@ static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num)
|
||||
}
|
||||
}
|
||||
|
||||
static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq)
|
||||
static qemu_irq spapr_qirq_xics(SpaprMachineState *spapr, int irq)
|
||||
{
|
||||
ICSState *ics = spapr->ics;
|
||||
uint32_t srcno = irq - ics->offset;
|
||||
@ -176,7 +176,7 @@ static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon)
|
||||
static void spapr_irq_print_info_xics(SpaprMachineState *spapr, Monitor *mon)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
@ -189,12 +189,12 @@ static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon)
|
||||
ics_pic_print_info(spapr->ics, mon);
|
||||
}
|
||||
|
||||
static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
|
||||
static void spapr_irq_cpu_intc_create_xics(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
Object *obj;
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr),
|
||||
&local_err);
|
||||
@ -206,7 +206,7 @@ static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
|
||||
spapr_cpu->icp = ICP(obj);
|
||||
}
|
||||
|
||||
static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
|
||||
static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id)
|
||||
{
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
CPUState *cs;
|
||||
@ -220,17 +220,17 @@ static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
|
||||
|
||||
static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
SpaprMachineState *spapr = opaque;
|
||||
|
||||
ics_simple_set_irq(spapr->ics, srcno, val);
|
||||
}
|
||||
|
||||
static void spapr_irq_reset_xics(sPAPRMachineState *spapr, Error **errp)
|
||||
static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
/* TODO: create the KVM XICS device */
|
||||
}
|
||||
|
||||
static const char *spapr_irq_get_nodename_xics(sPAPRMachineState *spapr)
|
||||
static const char *spapr_irq_get_nodename_xics(SpaprMachineState *spapr)
|
||||
{
|
||||
return XICS_NODENAME;
|
||||
}
|
||||
@ -239,7 +239,7 @@ static const char *spapr_irq_get_nodename_xics(sPAPRMachineState *spapr)
|
||||
#define SPAPR_IRQ_XICS_NR_MSIS \
|
||||
(XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
|
||||
|
||||
sPAPRIrq spapr_irq_xics = {
|
||||
SpaprIrq spapr_irq_xics = {
|
||||
.nr_irqs = SPAPR_IRQ_XICS_NR_IRQS,
|
||||
.nr_msis = SPAPR_IRQ_XICS_NR_MSIS,
|
||||
.ov5 = SPAPR_OV5_XIVE_LEGACY,
|
||||
@ -260,7 +260,7 @@ sPAPRIrq spapr_irq_xics = {
|
||||
/*
|
||||
* XIVE IRQ backend.
|
||||
*/
|
||||
static void spapr_irq_init_xive(sPAPRMachineState *spapr, int nr_irqs,
|
||||
static void spapr_irq_init_xive(SpaprMachineState *spapr, int nr_irqs,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
@ -294,7 +294,7 @@ static void spapr_irq_init_xive(sPAPRMachineState *spapr, int nr_irqs,
|
||||
spapr_xive_hcall_init(spapr);
|
||||
}
|
||||
|
||||
static int spapr_irq_claim_xive(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
static int spapr_irq_claim_xive(SpaprMachineState *spapr, int irq, bool lsi,
|
||||
Error **errp)
|
||||
{
|
||||
if (!spapr_xive_irq_claim(spapr->xive, irq, lsi)) {
|
||||
@ -304,7 +304,7 @@ static int spapr_irq_claim_xive(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spapr_irq_free_xive(sPAPRMachineState *spapr, int irq, int num)
|
||||
static void spapr_irq_free_xive(SpaprMachineState *spapr, int irq, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -313,9 +313,9 @@ static void spapr_irq_free_xive(sPAPRMachineState *spapr, int irq, int num)
|
||||
}
|
||||
}
|
||||
|
||||
static qemu_irq spapr_qirq_xive(sPAPRMachineState *spapr, int irq)
|
||||
static qemu_irq spapr_qirq_xive(SpaprMachineState *spapr, int irq)
|
||||
{
|
||||
sPAPRXive *xive = spapr->xive;
|
||||
SpaprXive *xive = spapr->xive;
|
||||
|
||||
if (irq >= xive->nr_irqs) {
|
||||
return NULL;
|
||||
@ -327,7 +327,7 @@ static qemu_irq spapr_qirq_xive(sPAPRMachineState *spapr, int irq)
|
||||
return spapr->qirqs[irq];
|
||||
}
|
||||
|
||||
static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
|
||||
static void spapr_irq_print_info_xive(SpaprMachineState *spapr,
|
||||
Monitor *mon)
|
||||
{
|
||||
CPUState *cs;
|
||||
@ -341,12 +341,12 @@ static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
|
||||
spapr_xive_pic_print_info(spapr->xive, mon);
|
||||
}
|
||||
|
||||
static void spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
|
||||
static void spapr_irq_cpu_intc_create_xive(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
Object *obj;
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
|
||||
if (local_err) {
|
||||
@ -363,12 +363,12 @@ static void spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
|
||||
spapr_xive_set_tctx_os_cam(spapr_cpu->tctx);
|
||||
}
|
||||
|
||||
static int spapr_irq_post_load_xive(sPAPRMachineState *spapr, int version_id)
|
||||
static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spapr_irq_reset_xive(sPAPRMachineState *spapr, Error **errp)
|
||||
static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
@ -385,12 +385,12 @@ static void spapr_irq_reset_xive(sPAPRMachineState *spapr, Error **errp)
|
||||
|
||||
static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
SpaprMachineState *spapr = opaque;
|
||||
|
||||
xive_source_set_irq(&spapr->xive->source, srcno, val);
|
||||
}
|
||||
|
||||
static const char *spapr_irq_get_nodename_xive(sPAPRMachineState *spapr)
|
||||
static const char *spapr_irq_get_nodename_xive(SpaprMachineState *spapr)
|
||||
{
|
||||
return spapr->xive->nodename;
|
||||
}
|
||||
@ -403,7 +403,7 @@ static const char *spapr_irq_get_nodename_xive(sPAPRMachineState *spapr)
|
||||
#define SPAPR_IRQ_XIVE_NR_IRQS 0x2000
|
||||
#define SPAPR_IRQ_XIVE_NR_MSIS (SPAPR_IRQ_XIVE_NR_IRQS - SPAPR_IRQ_MSI)
|
||||
|
||||
sPAPRIrq spapr_irq_xive = {
|
||||
SpaprIrq spapr_irq_xive = {
|
||||
.nr_irqs = SPAPR_IRQ_XIVE_NR_IRQS,
|
||||
.nr_msis = SPAPR_IRQ_XIVE_NR_MSIS,
|
||||
.ov5 = SPAPR_OV5_XIVE_EXPLOIT,
|
||||
@ -434,13 +434,13 @@ sPAPRIrq spapr_irq_xive = {
|
||||
* Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
|
||||
* default.
|
||||
*/
|
||||
static sPAPRIrq *spapr_irq_current(sPAPRMachineState *spapr)
|
||||
static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr)
|
||||
{
|
||||
return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
|
||||
&spapr_irq_xive : &spapr_irq_xics;
|
||||
}
|
||||
|
||||
static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs,
|
||||
static void spapr_irq_init_dual(SpaprMachineState *spapr, int nr_irqs,
|
||||
Error **errp)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
@ -464,7 +464,7 @@ static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs,
|
||||
}
|
||||
}
|
||||
|
||||
static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
static int spapr_irq_claim_dual(SpaprMachineState *spapr, int irq, bool lsi,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
@ -485,30 +485,30 @@ static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spapr_irq_free_dual(sPAPRMachineState *spapr, int irq, int num)
|
||||
static void spapr_irq_free_dual(SpaprMachineState *spapr, int irq, int num)
|
||||
{
|
||||
spapr_irq_xics.free(spapr, irq, num);
|
||||
spapr_irq_xive.free(spapr, irq, num);
|
||||
}
|
||||
|
||||
static qemu_irq spapr_qirq_dual(sPAPRMachineState *spapr, int irq)
|
||||
static qemu_irq spapr_qirq_dual(SpaprMachineState *spapr, int irq)
|
||||
{
|
||||
return spapr_irq_current(spapr)->qirq(spapr, irq);
|
||||
}
|
||||
|
||||
static void spapr_irq_print_info_dual(sPAPRMachineState *spapr, Monitor *mon)
|
||||
static void spapr_irq_print_info_dual(SpaprMachineState *spapr, Monitor *mon)
|
||||
{
|
||||
spapr_irq_current(spapr)->print_info(spapr, mon);
|
||||
}
|
||||
|
||||
static void spapr_irq_dt_populate_dual(sPAPRMachineState *spapr,
|
||||
static void spapr_irq_dt_populate_dual(SpaprMachineState *spapr,
|
||||
uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle)
|
||||
{
|
||||
spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
|
||||
}
|
||||
|
||||
static void spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
|
||||
static void spapr_irq_cpu_intc_create_dual(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
@ -522,7 +522,7 @@ static void spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
|
||||
spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
|
||||
}
|
||||
|
||||
static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
|
||||
static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id)
|
||||
{
|
||||
/*
|
||||
* Force a reset of the XIVE backend after migration. The machine
|
||||
@ -535,7 +535,7 @@ static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
|
||||
return spapr_irq_current(spapr)->post_load(spapr, version_id);
|
||||
}
|
||||
|
||||
static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
|
||||
static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
/*
|
||||
* Deactivate the XIVE MMIOs. The XIVE backend will reenable them
|
||||
@ -548,12 +548,12 @@ static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
|
||||
|
||||
static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
SpaprMachineState *spapr = opaque;
|
||||
|
||||
spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
|
||||
}
|
||||
|
||||
static const char *spapr_irq_get_nodename_dual(sPAPRMachineState *spapr)
|
||||
static const char *spapr_irq_get_nodename_dual(SpaprMachineState *spapr)
|
||||
{
|
||||
return spapr_irq_current(spapr)->get_nodename(spapr);
|
||||
}
|
||||
@ -564,7 +564,7 @@ static const char *spapr_irq_get_nodename_dual(sPAPRMachineState *spapr)
|
||||
#define SPAPR_IRQ_DUAL_NR_IRQS 0x2000
|
||||
#define SPAPR_IRQ_DUAL_NR_MSIS (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
|
||||
|
||||
sPAPRIrq spapr_irq_dual = {
|
||||
SpaprIrq spapr_irq_dual = {
|
||||
.nr_irqs = SPAPR_IRQ_DUAL_NR_IRQS,
|
||||
.nr_msis = SPAPR_IRQ_DUAL_NR_MSIS,
|
||||
.ov5 = SPAPR_OV5_XIVE_BOTH,
|
||||
@ -585,7 +585,7 @@ sPAPRIrq spapr_irq_dual = {
|
||||
/*
|
||||
* sPAPR IRQ frontend routines for devices
|
||||
*/
|
||||
void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
|
||||
void spapr_irq_init(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
|
||||
@ -611,34 +611,34 @@ void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
|
||||
spapr->irq->nr_irqs);
|
||||
}
|
||||
|
||||
int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp)
|
||||
int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp)
|
||||
{
|
||||
return spapr->irq->claim(spapr, irq, lsi, errp);
|
||||
}
|
||||
|
||||
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num)
|
||||
void spapr_irq_free(SpaprMachineState *spapr, int irq, int num)
|
||||
{
|
||||
spapr->irq->free(spapr, irq, num);
|
||||
}
|
||||
|
||||
qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq)
|
||||
qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq)
|
||||
{
|
||||
return spapr->irq->qirq(spapr, irq);
|
||||
}
|
||||
|
||||
int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id)
|
||||
int spapr_irq_post_load(SpaprMachineState *spapr, int version_id)
|
||||
{
|
||||
return spapr->irq->post_load(spapr, version_id);
|
||||
}
|
||||
|
||||
void spapr_irq_reset(sPAPRMachineState *spapr, Error **errp)
|
||||
void spapr_irq_reset(SpaprMachineState *spapr, Error **errp)
|
||||
{
|
||||
if (spapr->irq->reset) {
|
||||
spapr->irq->reset(spapr, errp);
|
||||
}
|
||||
}
|
||||
|
||||
int spapr_irq_get_phandle(sPAPRMachineState *spapr, void *fdt, Error **errp)
|
||||
int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp)
|
||||
{
|
||||
const char *nodename = spapr->irq->get_nodename(spapr);
|
||||
int offset, phandle;
|
||||
@ -684,7 +684,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
|
||||
int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp)
|
||||
{
|
||||
ICSState *ics = spapr->ics;
|
||||
int first = -1;
|
||||
@ -716,7 +716,7 @@ int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp)
|
||||
|
||||
#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS 0x400
|
||||
|
||||
sPAPRIrq spapr_irq_xics_legacy = {
|
||||
SpaprIrq spapr_irq_xics_legacy = {
|
||||
.nr_irqs = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
|
||||
.nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_IRQS,
|
||||
.ov5 = SPAPR_OV5_XIVE_LEGACY,
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "qemu/bitmap.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "trace.h"
|
||||
#include <libfdt.h>
|
||||
|
||||
@ -27,7 +26,7 @@
|
||||
* allows us to more safely make assumptions about the bitmap size and
|
||||
* simplify the calling code somewhat
|
||||
*/
|
||||
struct sPAPROptionVector {
|
||||
struct SpaprOptionVector {
|
||||
unsigned long *bitmap;
|
||||
int32_t bitmap_size; /* only used for migration */
|
||||
};
|
||||
@ -37,25 +36,25 @@ const VMStateDescription vmstate_spapr_ovec = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_BITMAP(bitmap, sPAPROptionVector, 1, bitmap_size),
|
||||
VMSTATE_BITMAP(bitmap, SpaprOptionVector, 1, bitmap_size),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
sPAPROptionVector *spapr_ovec_new(void)
|
||||
SpaprOptionVector *spapr_ovec_new(void)
|
||||
{
|
||||
sPAPROptionVector *ov;
|
||||
SpaprOptionVector *ov;
|
||||
|
||||
ov = g_new0(sPAPROptionVector, 1);
|
||||
ov = g_new0(SpaprOptionVector, 1);
|
||||
ov->bitmap = bitmap_new(OV_MAXBITS);
|
||||
ov->bitmap_size = OV_MAXBITS;
|
||||
|
||||
return ov;
|
||||
}
|
||||
|
||||
sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig)
|
||||
SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig)
|
||||
{
|
||||
sPAPROptionVector *ov;
|
||||
SpaprOptionVector *ov;
|
||||
|
||||
g_assert(ov_orig);
|
||||
|
||||
@ -65,9 +64,9 @@ sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig)
|
||||
return ov;
|
||||
}
|
||||
|
||||
void spapr_ovec_intersect(sPAPROptionVector *ov,
|
||||
sPAPROptionVector *ov1,
|
||||
sPAPROptionVector *ov2)
|
||||
void spapr_ovec_intersect(SpaprOptionVector *ov,
|
||||
SpaprOptionVector *ov1,
|
||||
SpaprOptionVector *ov2)
|
||||
{
|
||||
g_assert(ov);
|
||||
g_assert(ov1);
|
||||
@ -77,9 +76,9 @@ void spapr_ovec_intersect(sPAPROptionVector *ov,
|
||||
}
|
||||
|
||||
/* returns true if options bits were removed, false otherwise */
|
||||
bool spapr_ovec_diff(sPAPROptionVector *ov,
|
||||
sPAPROptionVector *ov_old,
|
||||
sPAPROptionVector *ov_new)
|
||||
bool spapr_ovec_diff(SpaprOptionVector *ov,
|
||||
SpaprOptionVector *ov_old,
|
||||
SpaprOptionVector *ov_new)
|
||||
{
|
||||
unsigned long *change_mask = bitmap_new(OV_MAXBITS);
|
||||
unsigned long *removed_bits = bitmap_new(OV_MAXBITS);
|
||||
@ -103,7 +102,7 @@ bool spapr_ovec_diff(sPAPROptionVector *ov,
|
||||
return bits_were_removed;
|
||||
}
|
||||
|
||||
void spapr_ovec_cleanup(sPAPROptionVector *ov)
|
||||
void spapr_ovec_cleanup(SpaprOptionVector *ov)
|
||||
{
|
||||
if (ov) {
|
||||
g_free(ov->bitmap);
|
||||
@ -111,7 +110,7 @@ void spapr_ovec_cleanup(sPAPROptionVector *ov)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_ovec_set(sPAPROptionVector *ov, long bitnr)
|
||||
void spapr_ovec_set(SpaprOptionVector *ov, long bitnr)
|
||||
{
|
||||
g_assert(ov);
|
||||
g_assert(bitnr < OV_MAXBITS);
|
||||
@ -119,7 +118,7 @@ void spapr_ovec_set(sPAPROptionVector *ov, long bitnr)
|
||||
set_bit(bitnr, ov->bitmap);
|
||||
}
|
||||
|
||||
void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr)
|
||||
void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr)
|
||||
{
|
||||
g_assert(ov);
|
||||
g_assert(bitnr < OV_MAXBITS);
|
||||
@ -127,16 +126,11 @@ void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr)
|
||||
clear_bit(bitnr, ov->bitmap);
|
||||
}
|
||||
|
||||
bool spapr_ovec_test(sPAPROptionVector *ov, long bitnr)
|
||||
bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr)
|
||||
{
|
||||
g_assert(ov);
|
||||
g_assert(bitnr < OV_MAXBITS);
|
||||
|
||||
/* support memory unplug for qtest */
|
||||
if (qtest_enabled() && bitnr == OV5_HP_EVT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return test_bit(bitnr, ov->bitmap) ? true : false;
|
||||
}
|
||||
|
||||
@ -184,9 +178,9 @@ static target_ulong vector_addr(target_ulong table_addr, int vector)
|
||||
return table_addr;
|
||||
}
|
||||
|
||||
sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
|
||||
SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
|
||||
{
|
||||
sPAPROptionVector *ov;
|
||||
SpaprOptionVector *ov;
|
||||
target_ulong addr;
|
||||
uint16_t vector_len;
|
||||
int i;
|
||||
@ -216,7 +210,7 @@ sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector)
|
||||
}
|
||||
|
||||
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
|
||||
sPAPROptionVector *ov, const char *name)
|
||||
SpaprOptionVector *ov, const char *name)
|
||||
{
|
||||
uint8_t vec[OV_MAXBYTES + 1];
|
||||
uint16_t vec_len;
|
||||
|
@ -61,9 +61,9 @@
|
||||
#define RTAS_TYPE_MSI 1
|
||||
#define RTAS_TYPE_MSIX 2
|
||||
|
||||
sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
|
||||
SpaprPhbState *spapr_pci_find_phb(SpaprMachineState *spapr, uint64_t buid)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
|
||||
QLIST_FOREACH(sphb, &spapr->phbs, list) {
|
||||
if (sphb->buid != buid) {
|
||||
@ -75,10 +75,10 @@ sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
|
||||
PCIDevice *spapr_pci_find_dev(SpaprMachineState *spapr, uint64_t buid,
|
||||
uint32_t config_addr)
|
||||
{
|
||||
sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid);
|
||||
SpaprPhbState *sphb = spapr_pci_find_phb(spapr, buid);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
|
||||
int bus_num = (config_addr >> 16) & 0xFF;
|
||||
int devfn = (config_addr >> 8) & 0xFF;
|
||||
@ -96,7 +96,7 @@ static uint32_t rtas_pci_cfgaddr(uint32_t arg)
|
||||
return ((arg >> 20) & 0xf00) | (arg & 0xff);
|
||||
}
|
||||
|
||||
static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
|
||||
static void finish_read_pci_config(SpaprMachineState *spapr, uint64_t buid,
|
||||
uint32_t addr, uint32_t size,
|
||||
target_ulong rets)
|
||||
{
|
||||
@ -126,7 +126,7 @@ static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid,
|
||||
rtas_st(rets, 1, val);
|
||||
}
|
||||
|
||||
static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -146,7 +146,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
finish_read_pci_config(spapr, buid, addr, size, rets);
|
||||
}
|
||||
|
||||
static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_read_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -164,7 +164,7 @@ static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
finish_read_pci_config(spapr, 0, addr, size, rets);
|
||||
}
|
||||
|
||||
static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
|
||||
static void finish_write_pci_config(SpaprMachineState *spapr, uint64_t buid,
|
||||
uint32_t addr, uint32_t size,
|
||||
uint32_t val, target_ulong rets)
|
||||
{
|
||||
@ -192,7 +192,7 @@ static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -213,7 +213,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
finish_write_pci_config(spapr, buid, addr, size, val, rets);
|
||||
}
|
||||
|
||||
static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_write_pci_config(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -262,12 +262,12 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
|
||||
uint32_t config_addr = rtas_ld(args, 0);
|
||||
uint64_t buid = rtas_ldq(args, 1);
|
||||
unsigned int func = rtas_ld(args, 3);
|
||||
@ -275,14 +275,14 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
unsigned int seq_num = rtas_ld(args, 5);
|
||||
unsigned int ret_intr_type;
|
||||
unsigned int irq, max_irqs = 0;
|
||||
sPAPRPHBState *phb = NULL;
|
||||
SpaprPhbState *phb = NULL;
|
||||
PCIDevice *pdev = NULL;
|
||||
spapr_pci_msi *msi;
|
||||
int *config_addr_key;
|
||||
Error *err = NULL;
|
||||
int i;
|
||||
|
||||
/* Fins sPAPRPHBState */
|
||||
/* Fins SpaprPhbState */
|
||||
phb = spapr_pci_find_phb(spapr, buid);
|
||||
if (phb) {
|
||||
pdev = spapr_pci_find_dev(spapr, buid, config_addr);
|
||||
@ -439,7 +439,7 @@ out:
|
||||
}
|
||||
|
||||
static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs,
|
||||
target_ulong args,
|
||||
@ -449,11 +449,11 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
|
||||
uint32_t config_addr = rtas_ld(args, 0);
|
||||
uint64_t buid = rtas_ldq(args, 1);
|
||||
unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3);
|
||||
sPAPRPHBState *phb = NULL;
|
||||
SpaprPhbState *phb = NULL;
|
||||
PCIDevice *pdev = NULL;
|
||||
spapr_pci_msi *msi;
|
||||
|
||||
/* Find sPAPRPHBState */
|
||||
/* Find SpaprPhbState */
|
||||
phb = spapr_pci_find_phb(spapr, buid);
|
||||
if (phb) {
|
||||
pdev = spapr_pci_find_dev(spapr, buid, config_addr);
|
||||
@ -480,12 +480,12 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint32_t addr, option;
|
||||
uint64_t buid;
|
||||
int ret;
|
||||
@ -516,12 +516,12 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
PCIDevice *pdev;
|
||||
uint32_t addr, option;
|
||||
uint64_t buid;
|
||||
@ -570,12 +570,12 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint64_t buid;
|
||||
int state, ret;
|
||||
|
||||
@ -612,12 +612,12 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint32_t option;
|
||||
uint64_t buid;
|
||||
int ret;
|
||||
@ -646,12 +646,12 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint64_t buid;
|
||||
int ret;
|
||||
|
||||
@ -679,12 +679,12 @@ param_error_exit:
|
||||
|
||||
/* To support it later */
|
||||
static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
int option;
|
||||
uint64_t buid;
|
||||
|
||||
@ -741,7 +741,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
|
||||
* Here we use the number returned by pci_spapr_map_irq to find a
|
||||
* corresponding qemu_irq.
|
||||
*/
|
||||
sPAPRPHBState *phb = opaque;
|
||||
SpaprPhbState *phb = opaque;
|
||||
|
||||
trace_spapr_pci_lsi_set(phb->dtbusname, irq_num, phb->lsi_table[irq_num].irq);
|
||||
qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
|
||||
@ -749,7 +749,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
|
||||
|
||||
static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
|
||||
{
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(opaque);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(opaque);
|
||||
PCIINTxRoute route;
|
||||
|
||||
route.mode = PCI_INTX_ENABLED;
|
||||
@ -766,7 +766,7 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin)
|
||||
static void spapr_msi_write(void *opaque, hwaddr addr,
|
||||
uint64_t data, unsigned size)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
uint32_t irq = data;
|
||||
|
||||
trace_spapr_pci_msi_write(addr, data, irq);
|
||||
@ -786,12 +786,12 @@ static const MemoryRegionOps spapr_msi_ops = {
|
||||
*/
|
||||
static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
||||
{
|
||||
sPAPRPHBState *phb = opaque;
|
||||
SpaprPhbState *phb = opaque;
|
||||
|
||||
return &phb->iommu_as;
|
||||
}
|
||||
|
||||
static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
|
||||
static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
|
||||
{
|
||||
char *path = NULL, *buf = NULL, *host = NULL;
|
||||
|
||||
@ -822,7 +822,7 @@ err_out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev)
|
||||
static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
|
||||
{
|
||||
char *buf;
|
||||
const char *devtype = "qemu";
|
||||
@ -1249,11 +1249,11 @@ static gchar *pci_get_node_name(PCIDevice *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
|
||||
static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
|
||||
PCIDevice *pdev);
|
||||
|
||||
static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
|
||||
sPAPRPHBState *sphb)
|
||||
SpaprPhbState *sphb)
|
||||
{
|
||||
ResourceProps rp;
|
||||
bool is_bridge = false;
|
||||
@ -1358,7 +1358,7 @@ static void spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset,
|
||||
}
|
||||
|
||||
/* create OF node for pci device and required OF DT properties */
|
||||
static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
|
||||
static int spapr_create_pci_child_dt(SpaprPhbState *phb, PCIDevice *dev,
|
||||
void *fdt, int node_offset)
|
||||
{
|
||||
int offset;
|
||||
@ -1382,7 +1382,7 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
|
||||
static SpaprDrc *spapr_phb_get_pci_func_drc(SpaprPhbState *phb,
|
||||
uint32_t busnr,
|
||||
int32_t devfn)
|
||||
{
|
||||
@ -1390,17 +1390,17 @@ static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
|
||||
(phb->index << 16) | (busnr << 8) | devfn);
|
||||
}
|
||||
|
||||
static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb,
|
||||
static SpaprDrc *spapr_phb_get_pci_drc(SpaprPhbState *phb,
|
||||
PCIDevice *pdev)
|
||||
{
|
||||
uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev))));
|
||||
return spapr_phb_get_pci_func_drc(phb, busnr, pdev->devfn);
|
||||
}
|
||||
|
||||
static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
|
||||
static uint32_t spapr_phb_get_pci_drc_index(SpaprPhbState *phb,
|
||||
PCIDevice *pdev)
|
||||
{
|
||||
sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
|
||||
if (!drc) {
|
||||
return 0;
|
||||
@ -1409,11 +1409,11 @@ static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb,
|
||||
return spapr_drc_index(drc);
|
||||
}
|
||||
|
||||
int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp)
|
||||
{
|
||||
HotplugHandler *plug_handler = qdev_get_hotplug_handler(drc->dev);
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(plug_handler);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(plug_handler);
|
||||
PCIDevice *pdev = PCI_DEVICE(drc->dev);
|
||||
|
||||
*fdt_start_offset = spapr_create_pci_child_dt(sphb, pdev, fdt, 0);
|
||||
@ -1423,9 +1423,9 @@ int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
static void spapr_pci_plug(HotplugHandler *plug_handler,
|
||||
DeviceState *plugged_dev, Error **errp)
|
||||
{
|
||||
sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
|
||||
SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
|
||||
PCIDevice *pdev = PCI_DEVICE(plugged_dev);
|
||||
sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
Error *local_err = NULL;
|
||||
PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
|
||||
uint32_t slotnr = PCI_SLOT(pdev->devfn);
|
||||
@ -1472,9 +1472,9 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
sPAPRDRConnector *func_drc;
|
||||
sPAPRDRConnectorClass *func_drck;
|
||||
sPAPRDREntitySense state;
|
||||
SpaprDrc *func_drc;
|
||||
SpaprDrcClass *func_drck;
|
||||
SpaprDREntitySense state;
|
||||
|
||||
func_drc = spapr_phb_get_pci_func_drc(phb, pci_bus_num(bus),
|
||||
PCI_DEVFN(slotnr, i));
|
||||
@ -1513,9 +1513,9 @@ static void spapr_pci_unplug(HotplugHandler *plug_handler,
|
||||
static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
|
||||
DeviceState *plugged_dev, Error **errp)
|
||||
{
|
||||
sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
|
||||
SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
|
||||
PCIDevice *pdev = PCI_DEVICE(plugged_dev);
|
||||
sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
SpaprDrc *drc = spapr_phb_get_pci_drc(phb, pdev);
|
||||
|
||||
if (!phb->dr_enabled) {
|
||||
error_setg(errp, QERR_BUS_NO_HOTPLUG,
|
||||
@ -1529,9 +1529,9 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
|
||||
if (!spapr_drc_unplug_requested(drc)) {
|
||||
PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
|
||||
uint32_t slotnr = PCI_SLOT(pdev->devfn);
|
||||
sPAPRDRConnector *func_drc;
|
||||
sPAPRDRConnectorClass *func_drck;
|
||||
sPAPRDREntitySense state;
|
||||
SpaprDrc *func_drc;
|
||||
SpaprDrcClass *func_drck;
|
||||
SpaprDREntitySense state;
|
||||
int i;
|
||||
|
||||
/* ensure any other present functions are pending unplug */
|
||||
@ -1573,7 +1573,7 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
|
||||
|
||||
static void spapr_phb_finalizefn(Object *obj)
|
||||
{
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(obj);
|
||||
|
||||
g_free(sphb->dtbusname);
|
||||
sphb->dtbusname = NULL;
|
||||
@ -1581,11 +1581,11 @@ static void spapr_phb_finalizefn(Object *obj)
|
||||
|
||||
static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SysBusDevice *s = SYS_BUS_DEVICE(dev);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(s);
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(phb);
|
||||
SpaprTceTable *tcet;
|
||||
int i;
|
||||
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
|
||||
|
||||
@ -1608,7 +1608,7 @@ static void spapr_phb_unrealize(DeviceState *dev, Error **errp)
|
||||
|
||||
if (sphb->dr_enabled) {
|
||||
for (i = PCI_SLOT_MAX * 8 - 1; i >= 0; i--) {
|
||||
sPAPRDRConnector *drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
|
||||
SpaprDrc *drc = spapr_drc_by_id(TYPE_SPAPR_DRC_PCI,
|
||||
(sphb->index << 16) | i);
|
||||
|
||||
if (drc) {
|
||||
@ -1645,18 +1645,18 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
|
||||
/* We don't use SPAPR_MACHINE() in order to exit gracefully if the user
|
||||
* tries to add a sPAPR PHB to a non-pseries machine.
|
||||
*/
|
||||
sPAPRMachineState *spapr =
|
||||
(sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(),
|
||||
SpaprMachineState *spapr =
|
||||
(SpaprMachineState *) object_dynamic_cast(qdev_get_machine(),
|
||||
TYPE_SPAPR_MACHINE);
|
||||
sPAPRMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL;
|
||||
SpaprMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL;
|
||||
SysBusDevice *s = SYS_BUS_DEVICE(dev);
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(s);
|
||||
char *namebuf;
|
||||
int i;
|
||||
PCIBus *bus;
|
||||
uint64_t msi_window_size = 4096;
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
const unsigned windows_supported = spapr_phb_windows_supported(sphb);
|
||||
|
||||
if (!spapr) {
|
||||
@ -1855,10 +1855,10 @@ static int spapr_phb_children_reset(Object *child, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spapr_phb_dma_reset(sPAPRPHBState *sphb)
|
||||
void spapr_phb_dma_reset(SpaprPhbState *sphb)
|
||||
{
|
||||
int i;
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
|
||||
for (i = 0; i < SPAPR_PCI_DMA_MAX_WINDOWS; ++i) {
|
||||
tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[i]);
|
||||
@ -1876,7 +1876,7 @@ void spapr_phb_dma_reset(sPAPRPHBState *sphb)
|
||||
|
||||
static void spapr_phb_reset(DeviceState *qdev)
|
||||
{
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev);
|
||||
|
||||
spapr_phb_dma_reset(sphb);
|
||||
|
||||
@ -1889,27 +1889,27 @@ static void spapr_phb_reset(DeviceState *qdev)
|
||||
}
|
||||
|
||||
static Property spapr_phb_properties[] = {
|
||||
DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
|
||||
DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
|
||||
DEFINE_PROP_UINT32("index", SpaprPhbState, index, -1),
|
||||
DEFINE_PROP_UINT64("mem_win_size", SpaprPhbState, mem_win_size,
|
||||
SPAPR_PCI_MEM32_WIN_SIZE),
|
||||
DEFINE_PROP_UINT64("mem64_win_size", sPAPRPHBState, mem64_win_size,
|
||||
DEFINE_PROP_UINT64("mem64_win_size", SpaprPhbState, mem64_win_size,
|
||||
SPAPR_PCI_MEM64_WIN_SIZE),
|
||||
DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
|
||||
DEFINE_PROP_UINT64("io_win_size", SpaprPhbState, io_win_size,
|
||||
SPAPR_PCI_IO_WIN_SIZE),
|
||||
DEFINE_PROP_BOOL("dynamic-reconfiguration", sPAPRPHBState, dr_enabled,
|
||||
DEFINE_PROP_BOOL("dynamic-reconfiguration", SpaprPhbState, dr_enabled,
|
||||
true),
|
||||
/* Default DMA window is 0..1GB */
|
||||
DEFINE_PROP_UINT64("dma_win_addr", sPAPRPHBState, dma_win_addr, 0),
|
||||
DEFINE_PROP_UINT64("dma_win_size", sPAPRPHBState, dma_win_size, 0x40000000),
|
||||
DEFINE_PROP_UINT64("dma64_win_addr", sPAPRPHBState, dma64_win_addr,
|
||||
DEFINE_PROP_UINT64("dma_win_addr", SpaprPhbState, dma_win_addr, 0),
|
||||
DEFINE_PROP_UINT64("dma_win_size", SpaprPhbState, dma_win_size, 0x40000000),
|
||||
DEFINE_PROP_UINT64("dma64_win_addr", SpaprPhbState, dma64_win_addr,
|
||||
0x800000000000000ULL),
|
||||
DEFINE_PROP_BOOL("ddw", sPAPRPHBState, ddw_enabled, true),
|
||||
DEFINE_PROP_UINT64("pgsz", sPAPRPHBState, page_size_mask,
|
||||
DEFINE_PROP_BOOL("ddw", SpaprPhbState, ddw_enabled, true),
|
||||
DEFINE_PROP_UINT64("pgsz", SpaprPhbState, page_size_mask,
|
||||
(1ULL << 12) | (1ULL << 16)),
|
||||
DEFINE_PROP_UINT32("numa_node", sPAPRPHBState, numa_node, -1),
|
||||
DEFINE_PROP_BOOL("pre-2.8-migration", sPAPRPHBState,
|
||||
DEFINE_PROP_UINT32("numa_node", SpaprPhbState, numa_node, -1),
|
||||
DEFINE_PROP_BOOL("pre-2.8-migration", SpaprPhbState,
|
||||
pre_2_8_migration, false),
|
||||
DEFINE_PROP_BOOL("pcie-extended-configuration-space", sPAPRPHBState,
|
||||
DEFINE_PROP_BOOL("pcie-extended-configuration-space", SpaprPhbState,
|
||||
pcie_ecs, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
@ -1939,7 +1939,7 @@ static const VMStateDescription vmstate_spapr_pci_msi = {
|
||||
|
||||
static int spapr_pci_pre_save(void *opaque)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
SpaprPhbState *sphb = opaque;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
int i;
|
||||
@ -1977,7 +1977,7 @@ static int spapr_pci_pre_save(void *opaque)
|
||||
|
||||
static int spapr_pci_post_load(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
SpaprPhbState *sphb = opaque;
|
||||
gpointer key, value;
|
||||
int i;
|
||||
|
||||
@ -1997,7 +1997,7 @@ static int spapr_pci_post_load(void *opaque, int version_id)
|
||||
|
||||
static bool pre_2_8_migration(void *opaque, int version_id)
|
||||
{
|
||||
sPAPRPHBState *sphb = opaque;
|
||||
SpaprPhbState *sphb = opaque;
|
||||
|
||||
return sphb->pre_2_8_migration;
|
||||
}
|
||||
@ -2009,16 +2009,16 @@ static const VMStateDescription vmstate_spapr_pci = {
|
||||
.pre_save = spapr_pci_pre_save,
|
||||
.post_load = spapr_pci_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState, NULL),
|
||||
VMSTATE_UINT32_TEST(mig_liobn, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_addr, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_size, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_io_win_addr, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_io_win_size, sPAPRPHBState, pre_2_8_migration),
|
||||
VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
|
||||
VMSTATE_UINT64_EQUAL(buid, SpaprPhbState, NULL),
|
||||
VMSTATE_UINT32_TEST(mig_liobn, SpaprPhbState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_addr, SpaprPhbState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_mem_win_size, SpaprPhbState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_io_win_addr, SpaprPhbState, pre_2_8_migration),
|
||||
VMSTATE_UINT64_TEST(mig_io_win_size, SpaprPhbState, pre_2_8_migration),
|
||||
VMSTATE_STRUCT_ARRAY(lsi_table, SpaprPhbState, PCI_NUM_PINS, 0,
|
||||
vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
|
||||
VMSTATE_INT32(msi_devs_num, sPAPRPHBState),
|
||||
VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, sPAPRPHBState, msi_devs_num, 0,
|
||||
VMSTATE_INT32(msi_devs_num, SpaprPhbState),
|
||||
VMSTATE_STRUCT_VARRAY_ALLOC(msi_devs, SpaprPhbState, msi_devs_num, 0,
|
||||
vmstate_spapr_pci_msi, spapr_pci_msi_mig),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
@ -2027,7 +2027,7 @@ static const VMStateDescription vmstate_spapr_pci = {
|
||||
static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge,
|
||||
PCIBus *rootbus)
|
||||
{
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(host_bridge);
|
||||
SpaprPhbState *sphb = SPAPR_PCI_HOST_BRIDGE(host_bridge);
|
||||
|
||||
return sphb->dtbusname;
|
||||
}
|
||||
@ -2055,7 +2055,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
|
||||
static const TypeInfo spapr_phb_info = {
|
||||
.name = TYPE_SPAPR_PCI_HOST_BRIDGE,
|
||||
.parent = TYPE_PCI_HOST_BRIDGE,
|
||||
.instance_size = sizeof(sPAPRPHBState),
|
||||
.instance_size = sizeof(SpaprPhbState),
|
||||
.instance_finalize = spapr_phb_finalizefn,
|
||||
.class_init = spapr_phb_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
@ -2064,19 +2064,19 @@ static const TypeInfo spapr_phb_info = {
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct sPAPRFDT {
|
||||
typedef struct SpaprFdt {
|
||||
void *fdt;
|
||||
int node_off;
|
||||
sPAPRPHBState *sphb;
|
||||
} sPAPRFDT;
|
||||
SpaprPhbState *sphb;
|
||||
} SpaprFdt;
|
||||
|
||||
static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev,
|
||||
void *opaque)
|
||||
{
|
||||
PCIBus *sec_bus;
|
||||
sPAPRFDT *p = opaque;
|
||||
SpaprFdt *p = opaque;
|
||||
int offset;
|
||||
sPAPRFDT s_fdt;
|
||||
SpaprFdt s_fdt;
|
||||
|
||||
offset = spapr_create_pci_child_dt(p->sphb, pdev, p->fdt, p->node_off);
|
||||
if (!offset) {
|
||||
@ -2128,7 +2128,7 @@ static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1);
|
||||
}
|
||||
|
||||
static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
|
||||
static void spapr_phb_pci_enumerate(SpaprPhbState *phb)
|
||||
{
|
||||
PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
|
||||
unsigned int bus_no = 0;
|
||||
@ -2139,7 +2139,7 @@ static void spapr_phb_pci_enumerate(sPAPRPHBState *phb)
|
||||
|
||||
}
|
||||
|
||||
int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
|
||||
int spapr_populate_pci_dt(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
|
||||
uint32_t nr_msis, int *node_offset)
|
||||
{
|
||||
int bus_off, i, j, ret;
|
||||
@ -2187,10 +2187,10 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
|
||||
cpu_to_be32(0x0),
|
||||
cpu_to_be32(0x0),
|
||||
cpu_to_be32(phb->numa_node)};
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
|
||||
sPAPRFDT s_fdt;
|
||||
sPAPRDRConnector *drc;
|
||||
SpaprFdt s_fdt;
|
||||
SpaprDrc *drc;
|
||||
|
||||
/* Start populating the FDT */
|
||||
nodename = g_strdup_printf("pci@%" PRIx64, phb->buid);
|
||||
@ -2345,8 +2345,8 @@ static int spapr_switch_one_vga(DeviceState *dev, void *opaque)
|
||||
|
||||
void spapr_pci_switch_vga(bool big_endian)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprPhbState *sphb;
|
||||
|
||||
/*
|
||||
* For backward compatibility with existing guests, we switch
|
||||
|
@ -28,12 +28,12 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
|
||||
bool spapr_phb_eeh_available(SpaprPhbState *sphb)
|
||||
{
|
||||
return vfio_eeh_as_ok(&sphb->iommu_as);
|
||||
}
|
||||
|
||||
static void spapr_phb_vfio_eeh_reenable(sPAPRPHBState *sphb)
|
||||
static void spapr_phb_vfio_eeh_reenable(SpaprPhbState *sphb)
|
||||
{
|
||||
vfio_eeh_as_op(&sphb->iommu_as, VFIO_EEH_PE_ENABLE);
|
||||
}
|
||||
@ -49,7 +49,7 @@ void spapr_phb_vfio_reset(DeviceState *qdev)
|
||||
spapr_phb_vfio_eeh_reenable(SPAPR_PCI_HOST_BRIDGE(qdev));
|
||||
}
|
||||
|
||||
int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||
int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
|
||||
unsigned int addr, int option)
|
||||
{
|
||||
uint32_t op;
|
||||
@ -96,7 +96,7 @@ int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
|
||||
int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -145,14 +145,14 @@ static void spapr_phb_vfio_eeh_clear_bus_msix(PCIBus *bus, void *opaque)
|
||||
spapr_phb_vfio_eeh_clear_dev_msix, NULL);
|
||||
}
|
||||
|
||||
static void spapr_phb_vfio_eeh_pre_reset(sPAPRPHBState *sphb)
|
||||
static void spapr_phb_vfio_eeh_pre_reset(SpaprPhbState *sphb)
|
||||
{
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
|
||||
|
||||
pci_for_each_bus(phb->bus, spapr_phb_vfio_eeh_clear_bus_msix, NULL);
|
||||
}
|
||||
|
||||
int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
||||
int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option)
|
||||
{
|
||||
uint32_t op;
|
||||
int ret;
|
||||
@ -181,7 +181,7 @@ int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
|
||||
int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -29,15 +29,15 @@
|
||||
#include "kvm_ppc.h"
|
||||
|
||||
#define SPAPR_RNG(obj) \
|
||||
OBJECT_CHECK(sPAPRRngState, (obj), TYPE_SPAPR_RNG)
|
||||
OBJECT_CHECK(SpaprRngState, (obj), TYPE_SPAPR_RNG)
|
||||
|
||||
struct sPAPRRngState {
|
||||
struct SpaprRngState {
|
||||
/*< private >*/
|
||||
DeviceState ds;
|
||||
RngBackend *backend;
|
||||
bool use_kvm;
|
||||
};
|
||||
typedef struct sPAPRRngState sPAPRRngState;
|
||||
typedef struct SpaprRngState SpaprRngState;
|
||||
|
||||
struct HRandomData {
|
||||
QemuSemaphore sem;
|
||||
@ -64,10 +64,10 @@ static void random_recv(void *dest, const void *src, size_t size)
|
||||
}
|
||||
|
||||
/* Handler for the H_RANDOM hypercall */
|
||||
static target_ulong h_random(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_random(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
sPAPRRngState *rngstate;
|
||||
SpaprRngState *rngstate;
|
||||
HRandomData hrdata;
|
||||
|
||||
rngstate = SPAPR_RNG(object_resolve_path_type("", TYPE_SPAPR_RNG, NULL));
|
||||
@ -109,7 +109,7 @@ static void spapr_rng_instance_init(Object *obj)
|
||||
static void spapr_rng_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
|
||||
sPAPRRngState *rngstate = SPAPR_RNG(dev);
|
||||
SpaprRngState *rngstate = SPAPR_RNG(dev);
|
||||
|
||||
if (rngstate->use_kvm) {
|
||||
if (kvmppc_enable_hwrng() == 0) {
|
||||
@ -133,8 +133,8 @@ static void spapr_rng_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
static Property spapr_rng_properties[] = {
|
||||
DEFINE_PROP_BOOL("use-kvm", sPAPRRngState, use_kvm, false),
|
||||
DEFINE_PROP_LINK("rng", sPAPRRngState, backend, TYPE_RNG_BACKEND,
|
||||
DEFINE_PROP_BOOL("use-kvm", SpaprRngState, use_kvm, false),
|
||||
DEFINE_PROP_LINK("rng", SpaprRngState, backend, TYPE_RNG_BACKEND,
|
||||
RngBackend *),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
@ -152,7 +152,7 @@ static void spapr_rng_class_init(ObjectClass *oc, void *data)
|
||||
static const TypeInfo spapr_rng_info = {
|
||||
.name = TYPE_SPAPR_RNG,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(sPAPRRngState),
|
||||
.instance_size = sizeof(SpaprRngState),
|
||||
.instance_init = spapr_rng_instance_init,
|
||||
.class_init = spapr_rng_class_init,
|
||||
};
|
||||
|
@ -50,13 +50,13 @@
|
||||
#include "target/ppc/mmu-hash64.h"
|
||||
#include "target/ppc/mmu-book3s-v3.h"
|
||||
|
||||
static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
uint8_t c = rtas_ld(args, 0);
|
||||
VIOsPAPRDevice *sdev = vty_lookup(spapr, 0);
|
||||
SpaprVioDevice *sdev = vty_lookup(spapr, 0);
|
||||
|
||||
if (!sdev) {
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
@ -66,7 +66,7 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
}
|
||||
|
||||
static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_power_off(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
@ -79,7 +79,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_system_reboot(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -93,7 +93,7 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
|
||||
static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -123,7 +123,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
}
|
||||
|
||||
static void rtas_start_cpu(PowerPCCPU *callcpu, sPAPRMachineState *spapr,
|
||||
static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -194,7 +194,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -226,7 +226,7 @@ static inline int sysparm_st(target_ulong addr, target_ulong len,
|
||||
}
|
||||
|
||||
static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -268,7 +268,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -288,7 +288,7 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
static void rtas_ibm_os_term(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -298,7 +298,7 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_set_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
@ -323,7 +323,7 @@ static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 1, 100);
|
||||
}
|
||||
|
||||
static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_get_power_level(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args, uint32_t nret,
|
||||
target_ulong rets)
|
||||
@ -353,7 +353,7 @@ static struct rtas_call {
|
||||
spapr_rtas_fn fn;
|
||||
} rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE];
|
||||
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
@ -387,7 +387,7 @@ uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
|
||||
|
||||
for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
|
||||
if (strcmp(cmd, rtas_table[token].name) == 0) {
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
|
||||
rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
|
||||
@ -425,7 +425,7 @@ void spapr_dt_rtas_tokens(void *fdt, int rtas)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr)
|
||||
void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr)
|
||||
{
|
||||
int rtas_node;
|
||||
int ret;
|
||||
|
@ -26,16 +26,16 @@
|
||||
|
||||
static int spapr_phb_get_active_win_num_cb(Object *child, void *opaque)
|
||||
{
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
|
||||
tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
|
||||
tcet = (SpaprTceTable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
|
||||
if (tcet && tcet->nb_table) {
|
||||
++*(unsigned *)opaque;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned spapr_phb_get_active_win_num(sPAPRPHBState *sphb)
|
||||
static unsigned spapr_phb_get_active_win_num(SpaprPhbState *sphb)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
|
||||
@ -46,9 +46,9 @@ static unsigned spapr_phb_get_active_win_num(sPAPRPHBState *sphb)
|
||||
|
||||
static int spapr_phb_get_free_liobn_cb(Object *child, void *opaque)
|
||||
{
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
|
||||
tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
|
||||
tcet = (SpaprTceTable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
|
||||
if (tcet && !tcet->nb_table) {
|
||||
*(uint32_t *)opaque = tcet->liobn;
|
||||
return 1;
|
||||
@ -56,7 +56,7 @@ static int spapr_phb_get_free_liobn_cb(Object *child, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned spapr_phb_get_free_liobn(sPAPRPHBState *sphb)
|
||||
static unsigned spapr_phb_get_free_liobn(SpaprPhbState *sphb)
|
||||
{
|
||||
uint32_t liobn = 0;
|
||||
|
||||
@ -90,12 +90,12 @@ static uint32_t spapr_page_mask_to_query_mask(uint64_t page_mask)
|
||||
}
|
||||
|
||||
static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint64_t buid;
|
||||
uint32_t avail, addr, pgmask = 0;
|
||||
|
||||
@ -129,13 +129,13 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
sPAPRTCETable *tcet = NULL;
|
||||
SpaprPhbState *sphb;
|
||||
SpaprTceTable *tcet = NULL;
|
||||
uint32_t addr, page_shift, window_shift, liobn;
|
||||
uint64_t buid, win_addr;
|
||||
int windows;
|
||||
@ -171,8 +171,18 @@ static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
win_addr = (windows == 0) ? sphb->dma_win_addr : sphb->dma64_win_addr;
|
||||
/*
|
||||
* We have just created a window, we know for the fact that it is empty,
|
||||
* use a hack to avoid iterating over the table as it is quite possible
|
||||
* to have billions of TCEs, all empty.
|
||||
* Note that we cannot delay this to the first H_PUT_TCE as this hcall is
|
||||
* mostly likely to be handled in KVM so QEMU just does not know if it
|
||||
* happened.
|
||||
*/
|
||||
tcet->skipping_replay = true;
|
||||
spapr_tce_table_enable(tcet, page_shift, win_addr,
|
||||
1ULL << (window_shift - page_shift));
|
||||
tcet->skipping_replay = false;
|
||||
if (!tcet->nb_table) {
|
||||
goto hw_error_exit;
|
||||
}
|
||||
@ -196,13 +206,13 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprPhbState *sphb;
|
||||
SpaprTceTable *tcet;
|
||||
uint32_t liobn;
|
||||
|
||||
if ((nargs != 1) || (nret != 1)) {
|
||||
@ -231,12 +241,12 @@ param_error_exit:
|
||||
}
|
||||
|
||||
static void rtas_ibm_reset_pe_dma_window(PowerPCCPU *cpu,
|
||||
sPAPRMachineState *spapr,
|
||||
SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRPHBState *sphb;
|
||||
SpaprPhbState *sphb;
|
||||
uint64_t buid;
|
||||
uint32_t addr;
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "qapi/qapi-events-target.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
|
||||
void spapr_rtc_read(SpaprRtcState *rtc, struct tm *tm, uint32_t *ns)
|
||||
{
|
||||
int64_t host_ns = qemu_clock_get_ns(rtc_clock);
|
||||
int64_t guest_ns;
|
||||
@ -53,7 +53,7 @@ void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
|
||||
}
|
||||
}
|
||||
|
||||
int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset)
|
||||
int spapr_rtc_import_offset(SpaprRtcState *rtc, int64_t legacy_offset)
|
||||
{
|
||||
if (!rtc) {
|
||||
return -ENODEV;
|
||||
@ -64,7 +64,7 @@ int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_get_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
@ -89,12 +89,12 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 7, ns);
|
||||
}
|
||||
|
||||
static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_set_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token, uint32_t nargs,
|
||||
target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
sPAPRRTCState *rtc = &spapr->rtc;
|
||||
SpaprRtcState *rtc = &spapr->rtc;
|
||||
struct tm tm;
|
||||
time_t new_s;
|
||||
int64_t host_ns;
|
||||
@ -134,7 +134,7 @@ static void spapr_rtc_qom_date(Object *obj, struct tm *current_tm, Error **errp)
|
||||
|
||||
static void spapr_rtc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRRTCState *rtc = SPAPR_RTC(dev);
|
||||
SpaprRtcState *rtc = SPAPR_RTC(dev);
|
||||
struct tm tm;
|
||||
time_t host_s;
|
||||
int64_t rtc_ns;
|
||||
@ -154,7 +154,7 @@ static const VMStateDescription vmstate_spapr_rtc = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT64(ns_offset, sPAPRRTCState),
|
||||
VMSTATE_INT64(ns_offset, SpaprRtcState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
@ -177,7 +177,7 @@ static void spapr_rtc_class_init(ObjectClass *oc, void *data)
|
||||
static const TypeInfo spapr_rtc_info = {
|
||||
.name = TYPE_SPAPR_RTC,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(sPAPRRTCState),
|
||||
.instance_size = sizeof(SpaprRtcState),
|
||||
.class_init = spapr_rtc_class_init,
|
||||
};
|
||||
|
||||
|
@ -46,8 +46,8 @@
|
||||
|
||||
static char *spapr_vio_get_dev_name(DeviceState *qdev)
|
||||
{
|
||||
VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
|
||||
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
SpaprVioDevice *dev = VIO_SPAPR_DEVICE(qdev);
|
||||
SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
/* Device tree style name device@reg */
|
||||
return g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
|
||||
@ -65,16 +65,16 @@ static const TypeInfo spapr_vio_bus_info = {
|
||||
.name = TYPE_SPAPR_VIO_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
.class_init = spapr_vio_bus_class_init,
|
||||
.instance_size = sizeof(VIOsPAPRBus),
|
||||
.instance_size = sizeof(SpaprVioBus),
|
||||
};
|
||||
|
||||
VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
|
||||
SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg)
|
||||
{
|
||||
BusChild *kid;
|
||||
VIOsPAPRDevice *dev = NULL;
|
||||
SpaprVioDevice *dev = NULL;
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
|
||||
dev = (VIOsPAPRDevice *)kid->child;
|
||||
dev = (SpaprVioDevice *)kid->child;
|
||||
if (dev->reg == reg) {
|
||||
return dev;
|
||||
}
|
||||
@ -83,10 +83,10 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||
static int vio_make_devnode(SpaprVioDevice *dev,
|
||||
void *fdt)
|
||||
{
|
||||
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
int vdevice_off, node_off, ret;
|
||||
char *dt_name;
|
||||
|
||||
@ -152,13 +152,13 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
|
||||
/*
|
||||
* CRQ handling
|
||||
*/
|
||||
static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_reg_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong queue_addr = args[1];
|
||||
target_ulong queue_len = args[2];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
|
||||
if (!dev) {
|
||||
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
|
||||
@ -197,7 +197,7 @@ static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong free_crq(VIOsPAPRDevice *dev)
|
||||
static target_ulong free_crq(SpaprVioDevice *dev)
|
||||
{
|
||||
dev->crq.qladdr = 0;
|
||||
dev->crq.qsize = 0;
|
||||
@ -208,11 +208,11 @@ static target_ulong free_crq(VIOsPAPRDevice *dev)
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_free_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
|
||||
if (!dev) {
|
||||
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
|
||||
@ -222,13 +222,13 @@ static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return free_crq(dev);
|
||||
}
|
||||
|
||||
static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_send_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong msg_hi = args[1];
|
||||
target_ulong msg_lo = args[2];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
uint64_t crq_mangle[2];
|
||||
|
||||
if (!dev) {
|
||||
@ -245,11 +245,11 @@ static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_HARDWARE;
|
||||
}
|
||||
|
||||
static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_enable_crq(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode, target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
|
||||
if (!dev) {
|
||||
hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
|
||||
@ -260,7 +260,7 @@ static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
|
||||
/* Returns negative error, 0 success, or positive: queue full */
|
||||
int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
|
||||
int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq)
|
||||
{
|
||||
int rc;
|
||||
uint8_t byte;
|
||||
@ -303,7 +303,7 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)
|
||||
|
||||
/* "quiesce" handling */
|
||||
|
||||
static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
|
||||
static void spapr_vio_quiesce_one(SpaprVioDevice *dev)
|
||||
{
|
||||
if (dev->tcet) {
|
||||
device_reset(DEVICE(dev->tcet));
|
||||
@ -311,7 +311,7 @@ static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
|
||||
free_crq(dev);
|
||||
}
|
||||
|
||||
void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
|
||||
void spapr_vio_set_bypass(SpaprVioDevice *dev, bool bypass)
|
||||
{
|
||||
if (!dev->tcet) {
|
||||
return;
|
||||
@ -323,13 +323,13 @@ void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
|
||||
dev->tcet->bypass = bypass;
|
||||
}
|
||||
|
||||
static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_set_tce_bypass(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
VIOsPAPRBus *bus = spapr->vio_bus;
|
||||
VIOsPAPRDevice *dev;
|
||||
SpaprVioBus *bus = spapr->vio_bus;
|
||||
SpaprVioDevice *dev;
|
||||
uint32_t unit, enable;
|
||||
|
||||
if (nargs != 2) {
|
||||
@ -354,14 +354,14 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static void rtas_quiesce(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets)
|
||||
{
|
||||
VIOsPAPRBus *bus = spapr->vio_bus;
|
||||
SpaprVioBus *bus = spapr->vio_bus;
|
||||
BusChild *kid;
|
||||
VIOsPAPRDevice *dev = NULL;
|
||||
SpaprVioDevice *dev = NULL;
|
||||
|
||||
if (nargs != 0) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
@ -369,18 +369,18 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
|
||||
dev = (VIOsPAPRDevice *)kid->child;
|
||||
dev = (SpaprVioDevice *)kid->child;
|
||||
spapr_vio_quiesce_one(dev);
|
||||
}
|
||||
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
|
||||
static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
|
||||
static SpaprVioDevice *reg_conflict(SpaprVioDevice *dev)
|
||||
{
|
||||
VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
|
||||
SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
|
||||
BusChild *kid;
|
||||
VIOsPAPRDevice *other;
|
||||
SpaprVioDevice *other;
|
||||
|
||||
/*
|
||||
* Check for a device other than the given one which is already
|
||||
@ -400,8 +400,8 @@ static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
|
||||
|
||||
static void spapr_vio_busdev_reset(DeviceState *qdev)
|
||||
{
|
||||
VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
|
||||
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
SpaprVioDevice *dev = VIO_SPAPR_DEVICE(qdev);
|
||||
SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
/* Shut down the request queue and TCEs if necessary */
|
||||
spapr_vio_quiesce_one(dev);
|
||||
@ -465,9 +465,9 @@ static inline uint32_t spapr_vio_reg_to_irq(uint32_t reg)
|
||||
|
||||
static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
|
||||
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprVioDevice *dev = (SpaprVioDevice *)qdev;
|
||||
SpaprVioDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
char *id;
|
||||
Error *local_err = NULL;
|
||||
|
||||
@ -478,7 +478,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
* rather than using spapr_vio_find_by_reg() because sdev
|
||||
* itself is already in the list.
|
||||
*/
|
||||
VIOsPAPRDevice *other = reg_conflict(dev);
|
||||
SpaprVioDevice *other = reg_conflict(dev);
|
||||
|
||||
if (other) {
|
||||
error_setg(errp, "%s and %s devices conflict at address %#x",
|
||||
@ -489,7 +489,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
}
|
||||
} else {
|
||||
/* Need to assign an address */
|
||||
VIOsPAPRBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
|
||||
SpaprVioBus *bus = SPAPR_VIO_BUS(dev->qdev.parent_bus);
|
||||
|
||||
do {
|
||||
dev->reg = bus->next_reg++;
|
||||
@ -540,14 +540,14 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
|
||||
pc->realize(dev, errp);
|
||||
}
|
||||
|
||||
static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
static target_ulong h_vio_signal(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
||||
target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
target_ulong reg = args[0];
|
||||
target_ulong mode = args[1];
|
||||
VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
VIOsPAPRDeviceClass *pc;
|
||||
SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
|
||||
SpaprVioDeviceClass *pc;
|
||||
|
||||
if (!dev) {
|
||||
return H_PARAMETER;
|
||||
@ -564,9 +564,9 @@ static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
VIOsPAPRBus *spapr_vio_bus_init(void)
|
||||
SpaprVioBus *spapr_vio_bus_init(void)
|
||||
{
|
||||
VIOsPAPRBus *bus;
|
||||
SpaprVioBus *bus;
|
||||
BusState *qbus;
|
||||
DeviceState *dev;
|
||||
|
||||
@ -615,14 +615,14 @@ const VMStateDescription vmstate_spapr_vio = {
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(reg, VIOsPAPRDevice, NULL),
|
||||
VMSTATE_UINT32_EQUAL(irq, VIOsPAPRDevice, NULL),
|
||||
VMSTATE_UINT32_EQUAL(reg, SpaprVioDevice, NULL),
|
||||
VMSTATE_UINT32_EQUAL(irq, SpaprVioDevice, NULL),
|
||||
|
||||
/* General VIO device state */
|
||||
VMSTATE_UINT64(signal_state, VIOsPAPRDevice),
|
||||
VMSTATE_UINT64(crq.qladdr, VIOsPAPRDevice),
|
||||
VMSTATE_UINT32(crq.qsize, VIOsPAPRDevice),
|
||||
VMSTATE_UINT32(crq.qnext, VIOsPAPRDevice),
|
||||
VMSTATE_UINT64(signal_state, SpaprVioDevice),
|
||||
VMSTATE_UINT64(crq.qladdr, SpaprVioDevice),
|
||||
VMSTATE_UINT32(crq.qsize, SpaprVioDevice),
|
||||
VMSTATE_UINT32(crq.qnext, SpaprVioDevice),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
@ -639,9 +639,9 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
|
||||
static const TypeInfo spapr_vio_type_info = {
|
||||
.name = TYPE_VIO_SPAPR_DEVICE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(VIOsPAPRDevice),
|
||||
.instance_size = sizeof(SpaprVioDevice),
|
||||
.abstract = true,
|
||||
.class_size = sizeof(VIOsPAPRDeviceClass),
|
||||
.class_size = sizeof(SpaprVioDeviceClass),
|
||||
.class_init = vio_spapr_device_class_init,
|
||||
};
|
||||
|
||||
@ -656,10 +656,10 @@ type_init(spapr_vio_register_types)
|
||||
|
||||
static int compare_reg(const void *p1, const void *p2)
|
||||
{
|
||||
VIOsPAPRDevice const *dev1, *dev2;
|
||||
SpaprVioDevice const *dev1, *dev2;
|
||||
|
||||
dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1;
|
||||
dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2;
|
||||
dev1 = (SpaprVioDevice *)*(DeviceState **)p1;
|
||||
dev2 = (SpaprVioDevice *)*(DeviceState **)p2;
|
||||
|
||||
if (dev1->reg < dev2->reg) {
|
||||
return -1;
|
||||
@ -672,7 +672,7 @@ static int compare_reg(const void *p1, const void *p2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
|
||||
void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt)
|
||||
{
|
||||
DeviceState *qdev, **qdevs;
|
||||
BusChild *kid;
|
||||
@ -707,8 +707,8 @@ void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
|
||||
/* Hack alert. Give the devices to libfdt in reverse order, we happen
|
||||
* to know that will mean they are in forward order in the tree. */
|
||||
for (i = num - 1; i >= 0; i--) {
|
||||
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
|
||||
VIOsPAPRDeviceClass *vdc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
SpaprVioDevice *dev = (SpaprVioDevice *)(qdevs[i]);
|
||||
SpaprVioDeviceClass *vdc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
ret = vio_make_devnode(dev, fdt);
|
||||
if (ret < 0) {
|
||||
@ -721,9 +721,9 @@ void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt)
|
||||
g_free(qdevs);
|
||||
}
|
||||
|
||||
gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus)
|
||||
gchar *spapr_vio_stdout_path(SpaprVioBus *bus)
|
||||
{
|
||||
VIOsPAPRDevice *dev;
|
||||
SpaprVioDevice *dev;
|
||||
char *name, *path;
|
||||
|
||||
dev = spapr_vty_get_default(bus);
|
||||
|
@ -91,7 +91,7 @@ typedef struct vscsi_req {
|
||||
OBJECT_CHECK(VSCSIState, (obj), TYPE_VIO_SPAPR_VSCSI_DEVICE)
|
||||
|
||||
typedef struct {
|
||||
VIOsPAPRDevice vdev;
|
||||
SpaprVioDevice vdev;
|
||||
SCSIBus bus;
|
||||
vscsi_req reqs[VSCSI_REQ_LIMIT];
|
||||
} VSCSIState;
|
||||
@ -1115,7 +1115,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
|
||||
}
|
||||
|
||||
|
||||
static int vscsi_do_crq(struct VIOsPAPRDevice *dev, uint8_t *crq_data)
|
||||
static int vscsi_do_crq(struct SpaprVioDevice *dev, uint8_t *crq_data)
|
||||
{
|
||||
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
|
||||
vscsi_crq crq;
|
||||
@ -1187,7 +1187,7 @@ static const struct SCSIBusInfo vscsi_scsi_info = {
|
||||
.load_request = vscsi_load_request,
|
||||
};
|
||||
|
||||
static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
|
||||
static void spapr_vscsi_reset(SpaprVioDevice *dev)
|
||||
{
|
||||
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
|
||||
int i;
|
||||
@ -1198,7 +1198,7 @@ static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void spapr_vscsi_realize(VIOsPAPRDevice *dev, Error **errp)
|
||||
static void spapr_vscsi_realize(SpaprVioDevice *dev, Error **errp)
|
||||
{
|
||||
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
|
||||
|
||||
@ -1208,7 +1208,7 @@ static void spapr_vscsi_realize(VIOsPAPRDevice *dev, Error **errp)
|
||||
&vscsi_scsi_info, NULL);
|
||||
}
|
||||
|
||||
void spapr_vscsi_create(VIOsPAPRBus *bus)
|
||||
void spapr_vscsi_create(SpaprVioBus *bus)
|
||||
{
|
||||
DeviceState *dev;
|
||||
|
||||
@ -1218,7 +1218,7 @@ void spapr_vscsi_create(VIOsPAPRBus *bus)
|
||||
scsi_bus_legacy_handle_cmdline(&VIO_SPAPR_VSCSI_DEVICE(dev)->bus);
|
||||
}
|
||||
|
||||
static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
|
||||
static int spapr_vscsi_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1256,7 +1256,7 @@ static const VMStateDescription vmstate_spapr_vscsi = {
|
||||
static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = spapr_vscsi_realize;
|
||||
k->reset = spapr_vscsi_reset;
|
||||
|
@ -729,7 +729,7 @@ static void vfio_listener_release(VFIOContainer *container)
|
||||
}
|
||||
}
|
||||
|
||||
static struct vfio_info_cap_header *
|
||||
struct vfio_info_cap_header *
|
||||
vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id)
|
||||
{
|
||||
struct vfio_info_cap_header *hdr;
|
||||
|
@ -143,19 +143,19 @@ int vfio_spapr_create_window(VFIOContainer *container,
|
||||
MemoryRegionSection *section,
|
||||
hwaddr *pgsize)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
|
||||
uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr);
|
||||
unsigned entries, pages;
|
||||
unsigned entries, bits_total, bits_per_level, max_levels;
|
||||
struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };
|
||||
long systempagesize = qemu_getrampagesize();
|
||||
long rampagesize = qemu_getrampagesize();
|
||||
|
||||
/*
|
||||
* The host might not support the guest supported IOMMU page size,
|
||||
* so we will use smaller physical IOMMU pages to back them.
|
||||
*/
|
||||
if (pagesize > systempagesize) {
|
||||
pagesize = systempagesize;
|
||||
if (pagesize > rampagesize) {
|
||||
pagesize = rampagesize;
|
||||
}
|
||||
pagesize = 1ULL << (63 - clz64(container->pgsizes &
|
||||
(pagesize | (pagesize - 1))));
|
||||
@ -176,16 +176,38 @@ int vfio_spapr_create_window(VFIOContainer *container,
|
||||
create.window_size = int128_get64(section->size);
|
||||
create.page_shift = ctz64(pagesize);
|
||||
/*
|
||||
* SPAPR host supports multilevel TCE tables, there is some
|
||||
* heuristic to decide how many levels we want for our table:
|
||||
* 0..64 = 1; 65..4096 = 2; 4097..262144 = 3; 262145.. = 4
|
||||
* SPAPR host supports multilevel TCE tables. We try to guess optimal
|
||||
* levels number and if this fails (for example due to the host memory
|
||||
* fragmentation), we increase levels. The DMA address structure is:
|
||||
* rrrrrrrr rxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx iiiiiiii
|
||||
* where:
|
||||
* r = reserved (bits >= 55 are reserved in the existing hardware)
|
||||
* i = IOMMU page offset (64K in this example)
|
||||
* x = bits to index a TCE which can be split to equal chunks to index
|
||||
* within the level.
|
||||
* The aim is to split "x" to smaller possible number of levels.
|
||||
*/
|
||||
entries = create.window_size >> create.page_shift;
|
||||
pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);
|
||||
pages = MAX(pow2ceil(pages), 1); /* Round up */
|
||||
create.levels = ctz64(pages) / 6 + 1;
|
||||
|
||||
ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
|
||||
/* bits_total is number of "x" needed */
|
||||
bits_total = ctz64(entries * sizeof(uint64_t));
|
||||
/*
|
||||
* bits_per_level is a safe guess of how much we can allocate per level:
|
||||
* 8 is the current minimum for CONFIG_FORCE_MAX_ZONEORDER and MAX_ORDER
|
||||
* is usually bigger than that.
|
||||
* Below we look at getpagesize() as TCEs are allocated from system pages.
|
||||
*/
|
||||
bits_per_level = ctz64(getpagesize()) + 8;
|
||||
create.levels = bits_total / bits_per_level;
|
||||
if (bits_total % bits_per_level) {
|
||||
++create.levels;
|
||||
}
|
||||
max_levels = (64 - create.page_shift) / ctz64(getpagesize());
|
||||
for ( ; create.levels <= max_levels; ++create.levels) {
|
||||
ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
error_report("Failed to create a window, ret = %d (%m)", ret);
|
||||
return -errno;
|
||||
@ -200,6 +222,7 @@ int vfio_spapr_create_window(VFIOContainer *container,
|
||||
return -EINVAL;
|
||||
}
|
||||
trace_vfio_spapr_create_window(create.page_shift,
|
||||
create.levels,
|
||||
create.window_size,
|
||||
create.start_addr);
|
||||
*pgsize = pagesize;
|
||||
|
@ -129,6 +129,6 @@ vfio_prereg_listener_region_add_skip(uint64_t start, uint64_t end) "0x%"PRIx64"
|
||||
vfio_prereg_listener_region_del_skip(uint64_t start, uint64_t end) "0x%"PRIx64" - 0x%"PRIx64
|
||||
vfio_prereg_register(uint64_t va, uint64_t size, int ret) "va=0x%"PRIx64" size=0x%"PRIx64" ret=%d"
|
||||
vfio_prereg_unregister(uint64_t va, uint64_t size, int ret) "va=0x%"PRIx64" size=0x%"PRIx64" ret=%d"
|
||||
vfio_spapr_create_window(int ps, uint64_t ws, uint64_t off) "pageshift=0x%x winsize=0x%"PRIx64" offset=0x%"PRIx64
|
||||
vfio_spapr_create_window(int ps, unsigned int levels, uint64_t ws, uint64_t off) "pageshift=0x%x levels=%u winsize=0x%"PRIx64" offset=0x%"PRIx64
|
||||
vfio_spapr_remove_window(uint64_t off) "offset=0x%"PRIx64
|
||||
vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d"
|
||||
|
@ -28,11 +28,11 @@
|
||||
#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
|
||||
|
||||
#define SPAPR_PCI_HOST_BRIDGE(obj) \
|
||||
OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
|
||||
OBJECT_CHECK(SpaprPhbState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
|
||||
|
||||
#define SPAPR_PCI_DMA_MAX_WINDOWS 2
|
||||
|
||||
typedef struct sPAPRPHBState sPAPRPHBState;
|
||||
typedef struct SpaprPhbState SpaprPhbState;
|
||||
|
||||
typedef struct spapr_pci_msi {
|
||||
uint32_t first_irq;
|
||||
@ -44,7 +44,7 @@ typedef struct spapr_pci_msi_mig {
|
||||
spapr_pci_msi value;
|
||||
} spapr_pci_msi_mig;
|
||||
|
||||
struct sPAPRPHBState {
|
||||
struct SpaprPhbState {
|
||||
PCIHostState parent_obj;
|
||||
|
||||
uint32_t index;
|
||||
@ -72,7 +72,7 @@ struct sPAPRPHBState {
|
||||
int32_t msi_devs_num;
|
||||
spapr_pci_msi_mig *msi_devs;
|
||||
|
||||
QLIST_ENTRY(sPAPRPHBState) list;
|
||||
QLIST_ENTRY(SpaprPhbState) list;
|
||||
|
||||
bool ddw_enabled;
|
||||
uint64_t page_size_mask;
|
||||
@ -105,56 +105,56 @@ struct sPAPRPHBState {
|
||||
|
||||
#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL
|
||||
|
||||
static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
|
||||
static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
|
||||
return spapr_qirq(spapr, phb->lsi_table[pin].irq);
|
||||
}
|
||||
|
||||
int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt,
|
||||
int spapr_populate_pci_dt(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
|
||||
uint32_t nr_msis, int *node_offset);
|
||||
|
||||
void spapr_pci_rtas_init(void);
|
||||
|
||||
sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid);
|
||||
PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid,
|
||||
SpaprPhbState *spapr_pci_find_phb(SpaprMachineState *spapr, uint64_t buid);
|
||||
PCIDevice *spapr_pci_find_dev(SpaprMachineState *spapr, uint64_t buid,
|
||||
uint32_t config_addr);
|
||||
|
||||
/* DRC callbacks */
|
||||
void spapr_phb_remove_pci_device_cb(DeviceState *dev);
|
||||
int spapr_pci_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp);
|
||||
|
||||
/* VFIO EEH hooks */
|
||||
#ifdef CONFIG_LINUX
|
||||
bool spapr_phb_eeh_available(sPAPRPHBState *sphb);
|
||||
int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||
bool spapr_phb_eeh_available(SpaprPhbState *sphb);
|
||||
int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
|
||||
unsigned int addr, int option);
|
||||
int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state);
|
||||
int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option);
|
||||
int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb);
|
||||
int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state);
|
||||
int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option);
|
||||
int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb);
|
||||
void spapr_phb_vfio_reset(DeviceState *qdev);
|
||||
#else
|
||||
static inline bool spapr_phb_eeh_available(sPAPRPHBState *sphb)
|
||||
static inline bool spapr_phb_eeh_available(SpaprPhbState *sphb)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
|
||||
static inline int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb,
|
||||
unsigned int addr, int option)
|
||||
{
|
||||
return RTAS_OUT_HW_ERROR;
|
||||
}
|
||||
static inline int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb,
|
||||
static inline int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb,
|
||||
int *state)
|
||||
{
|
||||
return RTAS_OUT_HW_ERROR;
|
||||
}
|
||||
static inline int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
|
||||
static inline int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option)
|
||||
{
|
||||
return RTAS_OUT_HW_ERROR;
|
||||
}
|
||||
static inline int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
|
||||
static inline int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb)
|
||||
{
|
||||
return RTAS_OUT_HW_ERROR;
|
||||
}
|
||||
@ -163,9 +163,9 @@ static inline void spapr_phb_vfio_reset(DeviceState *qdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
void spapr_phb_dma_reset(sPAPRPHBState *sphb);
|
||||
void spapr_phb_dma_reset(SpaprPhbState *sphb);
|
||||
|
||||
static inline unsigned spapr_phb_windows_supported(sPAPRPHBState *sphb)
|
||||
static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
|
||||
{
|
||||
return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "hw/ppc/pnv_lpc.h"
|
||||
#include "hw/ppc/pnv_psi.h"
|
||||
#include "hw/ppc/pnv_occ.h"
|
||||
#include "hw/ppc/pnv_xive.h"
|
||||
#include "hw/ppc/pnv_core.h"
|
||||
|
||||
#define TYPE_PNV_CHIP "pnv-chip"
|
||||
#define PNV_CHIP(obj) OBJECT_CHECK(PnvChip, (obj), TYPE_PNV_CHIP)
|
||||
@ -57,6 +59,8 @@ typedef struct PnvChip {
|
||||
MemoryRegion xscom_mmio;
|
||||
MemoryRegion xscom;
|
||||
AddressSpace xscom_as;
|
||||
|
||||
gchar *dt_isa_nodename;
|
||||
} PnvChip;
|
||||
|
||||
#define TYPE_PNV8_CHIP "pnv8-chip"
|
||||
@ -70,7 +74,7 @@ typedef struct Pnv8Chip {
|
||||
MemoryRegion icp_mmio;
|
||||
|
||||
PnvLpcController lpc;
|
||||
PnvPsi psi;
|
||||
Pnv8Psi psi;
|
||||
PnvOCC occ;
|
||||
} Pnv8Chip;
|
||||
|
||||
@ -82,6 +86,13 @@ typedef struct Pnv9Chip {
|
||||
PnvChip parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
PnvXive xive;
|
||||
Pnv9Psi psi;
|
||||
PnvLpcController lpc;
|
||||
PnvOCC occ;
|
||||
|
||||
uint32_t nr_quads;
|
||||
PnvQuad *quads;
|
||||
} Pnv9Chip;
|
||||
|
||||
typedef struct PnvChipClass {
|
||||
@ -100,6 +111,8 @@ typedef struct PnvChipClass {
|
||||
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
|
||||
void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
|
||||
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
|
||||
void (*dt_populate)(PnvChip *chip, void *fdt);
|
||||
void (*pic_print_info)(PnvChip *chip, Monitor *mon);
|
||||
} PnvChipClass;
|
||||
|
||||
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
|
||||
@ -215,4 +228,31 @@ void pnv_bmc_powerdown(IPMIBmc *bmc);
|
||||
(0x0003ffe000000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * \
|
||||
PNV_PSIHB_FSP_SIZE)
|
||||
|
||||
/*
|
||||
* POWER9 MMIO base addresses
|
||||
*/
|
||||
#define PNV9_CHIP_BASE(chip, base) \
|
||||
((base) + ((uint64_t) (chip)->chip_id << 42))
|
||||
|
||||
#define PNV9_XIVE_VC_SIZE 0x0000008000000000ull
|
||||
#define PNV9_XIVE_VC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006010000000000ull)
|
||||
|
||||
#define PNV9_XIVE_PC_SIZE 0x0000001000000000ull
|
||||
#define PNV9_XIVE_PC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006018000000000ull)
|
||||
|
||||
#define PNV9_LPCM_SIZE 0x0000000100000000ull
|
||||
#define PNV9_LPCM_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030000000000ull)
|
||||
|
||||
#define PNV9_PSIHB_SIZE 0x0000000000100000ull
|
||||
#define PNV9_PSIHB_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203000000ull)
|
||||
|
||||
#define PNV9_XIVE_IC_SIZE 0x0000000000080000ull
|
||||
#define PNV9_XIVE_IC_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203100000ull)
|
||||
|
||||
#define PNV9_XIVE_TM_SIZE 0x0000000000040000ull
|
||||
#define PNV9_XIVE_TM_BASE(chip) PNV9_CHIP_BASE(chip, 0x0006030203180000ull)
|
||||
|
||||
#define PNV9_PSIHB_ESB_SIZE 0x0000000000010000ull
|
||||
#define PNV9_PSIHB_ESB_BASE(chip) PNV9_CHIP_BASE(chip, 0x00060302031c0000ull)
|
||||
|
||||
#endif /* _PPC_PNV_H */
|
||||
|
@ -42,13 +42,15 @@ typedef struct PnvCore {
|
||||
|
||||
typedef struct PnvCoreClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
const MemoryRegionOps *xscom_ops;
|
||||
} PnvCoreClass;
|
||||
|
||||
#define PNV_CORE_TYPE_SUFFIX "-" TYPE_PNV_CORE
|
||||
#define PNV_CORE_TYPE_NAME(cpu_model) cpu_model PNV_CORE_TYPE_SUFFIX
|
||||
|
||||
typedef struct PnvCPUState {
|
||||
struct ICPState *icp;
|
||||
Object *intc;
|
||||
} PnvCPUState;
|
||||
|
||||
static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
|
||||
@ -56,4 +58,14 @@ static inline PnvCPUState *pnv_cpu_state(PowerPCCPU *cpu)
|
||||
return (PnvCPUState *)cpu->machine_data;
|
||||
}
|
||||
|
||||
#define TYPE_PNV_QUAD "powernv-cpu-quad"
|
||||
#define PNV_QUAD(obj) \
|
||||
OBJECT_CHECK(PnvQuad, (obj), TYPE_PNV_QUAD)
|
||||
|
||||
typedef struct PnvQuad {
|
||||
DeviceState parent_obj;
|
||||
|
||||
uint32_t id;
|
||||
MemoryRegion xscom_regs;
|
||||
} PnvQuad;
|
||||
#endif /* _PPC_PNV_CORE_H */
|
||||
|
@ -24,6 +24,11 @@
|
||||
#define TYPE_PNV_LPC "pnv-lpc"
|
||||
#define PNV_LPC(obj) \
|
||||
OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV_LPC)
|
||||
#define TYPE_PNV8_LPC TYPE_PNV_LPC "-POWER8"
|
||||
#define PNV8_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV8_LPC)
|
||||
|
||||
#define TYPE_PNV9_LPC TYPE_PNV_LPC "-POWER9"
|
||||
#define PNV9_LPC(obj) OBJECT_CHECK(PnvLpcController, (obj), TYPE_PNV9_LPC)
|
||||
|
||||
typedef struct PnvLpcController {
|
||||
DeviceState parent;
|
||||
@ -50,6 +55,8 @@ typedef struct PnvLpcController {
|
||||
MemoryRegion opb_master_regs;
|
||||
|
||||
/* OPB Master LS registers */
|
||||
uint32_t opb_irq_route0;
|
||||
uint32_t opb_irq_route1;
|
||||
uint32_t opb_irq_stat;
|
||||
uint32_t opb_irq_mask;
|
||||
uint32_t opb_irq_pol;
|
||||
@ -70,6 +77,25 @@ typedef struct PnvLpcController {
|
||||
PnvPsi *psi;
|
||||
} PnvLpcController;
|
||||
|
||||
#define PNV_LPC_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(PnvLpcClass, (klass), TYPE_PNV_LPC)
|
||||
#define PNV_LPC_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(PnvLpcClass, (obj), TYPE_PNV_LPC)
|
||||
|
||||
typedef struct PnvLpcClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
int psi_irq;
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
} PnvLpcClass;
|
||||
|
||||
/*
|
||||
* Old compilers error on typdef forward declarations. Keep them happy.
|
||||
*/
|
||||
struct PnvChip;
|
||||
|
||||
ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
|
||||
int pnv_dt_lpc(struct PnvChip *chip, void *fdt, int root_offset);
|
||||
|
||||
#endif /* _PPC_PNV_LPC_H */
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
#define TYPE_PNV_OCC "pnv-occ"
|
||||
#define PNV_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV_OCC)
|
||||
#define TYPE_PNV8_OCC TYPE_PNV_OCC "-POWER8"
|
||||
#define PNV8_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV8_OCC)
|
||||
#define TYPE_PNV9_OCC TYPE_PNV_OCC "-POWER9"
|
||||
#define PNV9_OCC(obj) OBJECT_CHECK(PnvOCC, (obj), TYPE_PNV9_OCC)
|
||||
|
||||
typedef struct PnvOCC {
|
||||
DeviceState xd;
|
||||
@ -35,4 +39,17 @@ typedef struct PnvOCC {
|
||||
MemoryRegion xscom_regs;
|
||||
} PnvOCC;
|
||||
|
||||
#define PNV_OCC_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(PnvOCCClass, (klass), TYPE_PNV_OCC)
|
||||
#define PNV_OCC_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(PnvOCCClass, (obj), TYPE_PNV_OCC)
|
||||
|
||||
typedef struct PnvOCCClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
int xscom_size;
|
||||
const MemoryRegionOps *xscom_ops;
|
||||
int psi_irq;
|
||||
} PnvOCCClass;
|
||||
|
||||
#endif /* _PPC_PNV_OCC_H */
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/ppc/xics.h"
|
||||
#include "hw/ppc/xive.h"
|
||||
|
||||
#define TYPE_PNV_PSI "pnv-psi"
|
||||
#define PNV_PSI(obj) \
|
||||
@ -39,7 +40,6 @@ typedef struct PnvPsi {
|
||||
uint64_t fsp_bar;
|
||||
|
||||
/* Interrupt generation */
|
||||
ICSState ics;
|
||||
qemu_irq *qirqs;
|
||||
|
||||
/* Registers */
|
||||
@ -48,6 +48,42 @@ typedef struct PnvPsi {
|
||||
MemoryRegion xscom_regs;
|
||||
} PnvPsi;
|
||||
|
||||
#define TYPE_PNV8_PSI TYPE_PNV_PSI "-POWER8"
|
||||
#define PNV8_PSI(obj) \
|
||||
OBJECT_CHECK(Pnv8Psi, (obj), TYPE_PNV8_PSI)
|
||||
|
||||
typedef struct Pnv8Psi {
|
||||
PnvPsi parent;
|
||||
|
||||
ICSState ics;
|
||||
} Pnv8Psi;
|
||||
|
||||
#define TYPE_PNV9_PSI TYPE_PNV_PSI "-POWER9"
|
||||
#define PNV9_PSI(obj) \
|
||||
OBJECT_CHECK(Pnv9Psi, (obj), TYPE_PNV9_PSI)
|
||||
|
||||
typedef struct Pnv9Psi {
|
||||
PnvPsi parent;
|
||||
|
||||
XiveSource source;
|
||||
} Pnv9Psi;
|
||||
|
||||
#define PNV_PSI_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(PnvPsiClass, (klass), TYPE_PNV_PSI)
|
||||
#define PNV_PSI_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(PnvPsiClass, (obj), TYPE_PNV_PSI)
|
||||
|
||||
typedef struct PnvPsiClass {
|
||||
SysBusDeviceClass parent_class;
|
||||
|
||||
int chip_type;
|
||||
uint32_t xscom_pcba;
|
||||
uint32_t xscom_size;
|
||||
uint64_t bar_mask;
|
||||
|
||||
void (*irq_set)(PnvPsi *psi, int, bool state);
|
||||
} PnvPsiClass;
|
||||
|
||||
/* The PSI and FSP interrupts are muxed on the same IRQ number */
|
||||
typedef enum PnvPsiIrq {
|
||||
PSIHB_IRQ_PSI, /* internal use only */
|
||||
@ -61,6 +97,25 @@ typedef enum PnvPsiIrq {
|
||||
|
||||
#define PSI_NUM_INTERRUPTS 6
|
||||
|
||||
extern void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state);
|
||||
void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
|
||||
|
||||
/* P9 PSI Interrupts */
|
||||
#define PSIHB9_IRQ_PSI 0
|
||||
#define PSIHB9_IRQ_OCC 1
|
||||
#define PSIHB9_IRQ_FSI 2
|
||||
#define PSIHB9_IRQ_LPCHC 3
|
||||
#define PSIHB9_IRQ_LOCAL_ERR 4
|
||||
#define PSIHB9_IRQ_GLOBAL_ERR 5
|
||||
#define PSIHB9_IRQ_TPM 6
|
||||
#define PSIHB9_IRQ_LPC_SIRQ0 7
|
||||
#define PSIHB9_IRQ_LPC_SIRQ1 8
|
||||
#define PSIHB9_IRQ_LPC_SIRQ2 9
|
||||
#define PSIHB9_IRQ_LPC_SIRQ3 10
|
||||
#define PSIHB9_IRQ_SBE_I2C 11
|
||||
#define PSIHB9_IRQ_DIO 12
|
||||
#define PSIHB9_IRQ_PSU 13
|
||||
#define PSIHB9_NUM_IRQS 14
|
||||
|
||||
void pnv_psi_pic_print_info(Pnv9Psi *psi, Monitor *mon);
|
||||
|
||||
#endif /* _PPC_PNV_PSI_H */
|
||||
|
93
include/hw/ppc/pnv_xive.h
Normal file
93
include/hw/ppc/pnv_xive.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* QEMU PowerPC XIVE interrupt controller model
|
||||
*
|
||||
* Copyright (c) 2017-2019, IBM Corporation.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See the
|
||||
* COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef PPC_PNV_XIVE_H
|
||||
#define PPC_PNV_XIVE_H
|
||||
|
||||
#include "hw/ppc/xive.h"
|
||||
|
||||
struct PnvChip;
|
||||
|
||||
#define TYPE_PNV_XIVE "pnv-xive"
|
||||
#define PNV_XIVE(obj) OBJECT_CHECK(PnvXive, (obj), TYPE_PNV_XIVE)
|
||||
|
||||
#define XIVE_BLOCK_MAX 16
|
||||
|
||||
#define XIVE_TABLE_BLK_MAX 16 /* Block Scope Table (0-15) */
|
||||
#define XIVE_TABLE_MIG_MAX 16 /* Migration Register Table (1-15) */
|
||||
#define XIVE_TABLE_VDT_MAX 16 /* VDT Domain Table (0-15) */
|
||||
#define XIVE_TABLE_EDT_MAX 64 /* EDT Domain Table (0-63) */
|
||||
|
||||
typedef struct PnvXive {
|
||||
XiveRouter parent_obj;
|
||||
|
||||
/* Owning chip */
|
||||
struct PnvChip *chip;
|
||||
|
||||
/* XSCOM addresses giving access to the controller registers */
|
||||
MemoryRegion xscom_regs;
|
||||
|
||||
/* Main MMIO regions that can be configured by FW */
|
||||
MemoryRegion ic_mmio;
|
||||
MemoryRegion ic_reg_mmio;
|
||||
MemoryRegion ic_notify_mmio;
|
||||
MemoryRegion ic_lsi_mmio;
|
||||
MemoryRegion tm_indirect_mmio;
|
||||
MemoryRegion vc_mmio;
|
||||
MemoryRegion pc_mmio;
|
||||
MemoryRegion tm_mmio;
|
||||
|
||||
/*
|
||||
* IPI and END address spaces modeling the EDT segmentation in the
|
||||
* VC region
|
||||
*/
|
||||
AddressSpace ipi_as;
|
||||
MemoryRegion ipi_mmio;
|
||||
MemoryRegion ipi_edt_mmio;
|
||||
|
||||
AddressSpace end_as;
|
||||
MemoryRegion end_mmio;
|
||||
MemoryRegion end_edt_mmio;
|
||||
|
||||
/* Shortcut values for the Main MMIO regions */
|
||||
hwaddr ic_base;
|
||||
uint32_t ic_shift;
|
||||
hwaddr vc_base;
|
||||
uint32_t vc_shift;
|
||||
hwaddr pc_base;
|
||||
uint32_t pc_shift;
|
||||
hwaddr tm_base;
|
||||
uint32_t tm_shift;
|
||||
|
||||
/* Our XIVE source objects for IPIs and ENDs */
|
||||
XiveSource ipi_source;
|
||||
XiveENDSource end_source;
|
||||
|
||||
/* Interrupt controller registers */
|
||||
uint64_t regs[0x300];
|
||||
|
||||
/* Can be configured by FW */
|
||||
uint32_t tctx_chipid;
|
||||
|
||||
/*
|
||||
* Virtual Structure Descriptor tables : EAT, SBE, ENDT, NVTT, IRQ
|
||||
* These are in a SRAM protected by ECC.
|
||||
*/
|
||||
uint64_t vsds[5][XIVE_BLOCK_MAX];
|
||||
|
||||
/* Translation tables */
|
||||
uint64_t blk[XIVE_TABLE_BLK_MAX];
|
||||
uint64_t mig[XIVE_TABLE_MIG_MAX];
|
||||
uint64_t vdt[XIVE_TABLE_VDT_MAX];
|
||||
uint64_t edt[XIVE_TABLE_EDT_MAX];
|
||||
} PnvXive;
|
||||
|
||||
void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon);
|
||||
|
||||
#endif /* PPC_PNV_XIVE_H */
|
@ -60,10 +60,6 @@ typedef struct PnvXScomInterfaceClass {
|
||||
(PNV_XSCOM_EX_CORE_BASE | ((uint64_t)(core) << 24))
|
||||
#define PNV_XSCOM_EX_SIZE 0x100000
|
||||
|
||||
#define PNV_XSCOM_P9_EC_BASE(core) \
|
||||
((uint64_t)(((core) & 0x1F) + 0x20) << 24)
|
||||
#define PNV_XSCOM_P9_EC_SIZE 0x100000
|
||||
|
||||
#define PNV_XSCOM_LPC_BASE 0xb0020
|
||||
#define PNV_XSCOM_LPC_SIZE 0x4
|
||||
|
||||
@ -73,6 +69,23 @@ typedef struct PnvXScomInterfaceClass {
|
||||
#define PNV_XSCOM_OCC_BASE 0x0066000
|
||||
#define PNV_XSCOM_OCC_SIZE 0x6000
|
||||
|
||||
#define PNV9_XSCOM_EC_BASE(core) \
|
||||
((uint64_t)(((core) & 0x1F) + 0x20) << 24)
|
||||
#define PNV9_XSCOM_EC_SIZE 0x100000
|
||||
|
||||
#define PNV9_XSCOM_EQ_BASE(core) \
|
||||
((uint64_t)(((core) & 0x1C) + 0x40) << 22)
|
||||
#define PNV9_XSCOM_EQ_SIZE 0x100000
|
||||
|
||||
#define PNV9_XSCOM_OCC_BASE PNV_XSCOM_OCC_BASE
|
||||
#define PNV9_XSCOM_OCC_SIZE 0x8000
|
||||
|
||||
#define PNV9_XSCOM_PSIHB_BASE 0x5012900
|
||||
#define PNV9_XSCOM_PSIHB_SIZE 0x100
|
||||
|
||||
#define PNV9_XSCOM_XIVE_BASE 0x5013000
|
||||
#define PNV9_XSCOM_XIVE_SIZE 0x300
|
||||
|
||||
extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
|
||||
extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "target/ppc/cpu-qom.h"
|
||||
|
||||
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
|
||||
PowerPCCPU *ppc_get_vcpu_by_pir(int pir);
|
||||
|
||||
/* PowerPC hardware exceptions management helpers */
|
||||
typedef void (*clk_setup_cb)(void *opaque, uint32_t freq);
|
||||
|
@ -8,16 +8,16 @@
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/ppc/spapr_ovec.h"
|
||||
#include "hw/ppc/spapr_irq.h"
|
||||
#include "hw/ppc/spapr_xive.h" /* For sPAPRXive */
|
||||
#include "hw/ppc/spapr_xive.h" /* For SpaprXive */
|
||||
#include "hw/ppc/xics.h" /* For ICSState */
|
||||
|
||||
struct VIOsPAPRBus;
|
||||
struct sPAPRPHBState;
|
||||
struct sPAPRNVRAM;
|
||||
struct SpaprVioBus;
|
||||
struct SpaprPhbState;
|
||||
struct SpaprNvram;
|
||||
|
||||
typedef struct sPAPREventLogEntry sPAPREventLogEntry;
|
||||
typedef struct sPAPREventSource sPAPREventSource;
|
||||
typedef struct sPAPRPendingHPT sPAPRPendingHPT;
|
||||
typedef struct SpaprEventLogEntry SpaprEventLogEntry;
|
||||
typedef struct SpaprEventSource SpaprEventSource;
|
||||
typedef struct SpaprPendingHpt SpaprPendingHpt;
|
||||
|
||||
#define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL
|
||||
#define SPAPR_ENTRY_POINT 0x100
|
||||
@ -27,32 +27,32 @@ typedef struct sPAPRPendingHPT sPAPRPendingHPT;
|
||||
#define TYPE_SPAPR_RTC "spapr-rtc"
|
||||
|
||||
#define SPAPR_RTC(obj) \
|
||||
OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC)
|
||||
OBJECT_CHECK(SpaprRtcState, (obj), TYPE_SPAPR_RTC)
|
||||
|
||||
typedef struct sPAPRRTCState sPAPRRTCState;
|
||||
struct sPAPRRTCState {
|
||||
typedef struct SpaprRtcState SpaprRtcState;
|
||||
struct SpaprRtcState {
|
||||
/*< private >*/
|
||||
DeviceState parent_obj;
|
||||
int64_t ns_offset;
|
||||
};
|
||||
|
||||
typedef struct sPAPRDIMMState sPAPRDIMMState;
|
||||
typedef struct sPAPRMachineClass sPAPRMachineClass;
|
||||
typedef struct SpaprDimmState SpaprDimmState;
|
||||
typedef struct SpaprMachineClass SpaprMachineClass;
|
||||
|
||||
#define TYPE_SPAPR_MACHINE "spapr-machine"
|
||||
#define SPAPR_MACHINE(obj) \
|
||||
OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE)
|
||||
OBJECT_CHECK(SpaprMachineState, (obj), TYPE_SPAPR_MACHINE)
|
||||
#define SPAPR_MACHINE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRMachineClass, obj, TYPE_SPAPR_MACHINE)
|
||||
OBJECT_GET_CLASS(SpaprMachineClass, obj, TYPE_SPAPR_MACHINE)
|
||||
#define SPAPR_MACHINE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE)
|
||||
OBJECT_CLASS_CHECK(SpaprMachineClass, klass, TYPE_SPAPR_MACHINE)
|
||||
|
||||
typedef enum {
|
||||
SPAPR_RESIZE_HPT_DEFAULT = 0,
|
||||
SPAPR_RESIZE_HPT_DISABLED,
|
||||
SPAPR_RESIZE_HPT_ENABLED,
|
||||
SPAPR_RESIZE_HPT_REQUIRED,
|
||||
} sPAPRResizeHPT;
|
||||
} SpaprResizeHpt;
|
||||
|
||||
/**
|
||||
* Capabilities
|
||||
@ -74,8 +74,12 @@ typedef enum {
|
||||
#define SPAPR_CAP_HPT_MAXPAGESIZE 0x06
|
||||
/* Nested KVM-HV */
|
||||
#define SPAPR_CAP_NESTED_KVM_HV 0x07
|
||||
/* Large Decrementer */
|
||||
#define SPAPR_CAP_LARGE_DECREMENTER 0x08
|
||||
/* Count Cache Flush Assist HW Instruction */
|
||||
#define SPAPR_CAP_CCF_ASSIST 0x09
|
||||
/* Num Caps */
|
||||
#define SPAPR_CAP_NUM (SPAPR_CAP_NESTED_KVM_HV + 1)
|
||||
#define SPAPR_CAP_NUM (SPAPR_CAP_CCF_ASSIST + 1)
|
||||
|
||||
/*
|
||||
* Capability Values
|
||||
@ -83,22 +87,27 @@ typedef enum {
|
||||
/* Bool Caps */
|
||||
#define SPAPR_CAP_OFF 0x00
|
||||
#define SPAPR_CAP_ON 0x01
|
||||
|
||||
/* Custom Caps */
|
||||
|
||||
/* Generic */
|
||||
#define SPAPR_CAP_BROKEN 0x00
|
||||
#define SPAPR_CAP_WORKAROUND 0x01
|
||||
#define SPAPR_CAP_FIXED 0x02
|
||||
/* SPAPR_CAP_IBS (cap-ibs) */
|
||||
#define SPAPR_CAP_FIXED_IBS 0x02
|
||||
#define SPAPR_CAP_FIXED_CCD 0x03
|
||||
#define SPAPR_CAP_FIXED_NA 0x10 /* Lets leave a bit of a gap... */
|
||||
|
||||
typedef struct sPAPRCapabilities sPAPRCapabilities;
|
||||
struct sPAPRCapabilities {
|
||||
typedef struct SpaprCapabilities SpaprCapabilities;
|
||||
struct SpaprCapabilities {
|
||||
uint8_t caps[SPAPR_CAP_NUM];
|
||||
};
|
||||
|
||||
/**
|
||||
* sPAPRMachineClass:
|
||||
* SpaprMachineClass:
|
||||
*/
|
||||
struct sPAPRMachineClass {
|
||||
struct SpaprMachineClass {
|
||||
/*< private >*/
|
||||
MachineClass parent_class;
|
||||
|
||||
@ -110,33 +119,33 @@ struct sPAPRMachineClass {
|
||||
bool pre_2_10_has_unused_icps;
|
||||
bool legacy_irq_allocation;
|
||||
|
||||
void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
|
||||
void (*phb_placement)(SpaprMachineState *spapr, uint32_t index,
|
||||
uint64_t *buid, hwaddr *pio,
|
||||
hwaddr *mmio32, hwaddr *mmio64,
|
||||
unsigned n_dma, uint32_t *liobns, Error **errp);
|
||||
sPAPRResizeHPT resize_hpt_default;
|
||||
sPAPRCapabilities default_caps;
|
||||
sPAPRIrq *irq;
|
||||
SpaprResizeHpt resize_hpt_default;
|
||||
SpaprCapabilities default_caps;
|
||||
SpaprIrq *irq;
|
||||
};
|
||||
|
||||
/**
|
||||
* sPAPRMachineState:
|
||||
* SpaprMachineState:
|
||||
*/
|
||||
struct sPAPRMachineState {
|
||||
struct SpaprMachineState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
|
||||
struct VIOsPAPRBus *vio_bus;
|
||||
QLIST_HEAD(, sPAPRPHBState) phbs;
|
||||
struct sPAPRNVRAM *nvram;
|
||||
struct SpaprVioBus *vio_bus;
|
||||
QLIST_HEAD(, SpaprPhbState) phbs;
|
||||
struct SpaprNvram *nvram;
|
||||
ICSState *ics;
|
||||
sPAPRRTCState rtc;
|
||||
SpaprRtcState rtc;
|
||||
|
||||
sPAPRResizeHPT resize_hpt;
|
||||
SpaprResizeHpt resize_hpt;
|
||||
void *htab;
|
||||
uint32_t htab_shift;
|
||||
uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROCESS_TABLE */
|
||||
sPAPRPendingHPT *pending_hpt; /* in-progress resize */
|
||||
SpaprPendingHpt *pending_hpt; /* in-progress resize */
|
||||
|
||||
hwaddr rma_size;
|
||||
int vrma_adjust;
|
||||
@ -155,15 +164,15 @@ struct sPAPRMachineState {
|
||||
uint32_t vsmt; /* Virtual SMT mode (KVM's "core stride") */
|
||||
|
||||
Notifier epow_notifier;
|
||||
QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
|
||||
QTAILQ_HEAD(, SpaprEventLogEntry) pending_events;
|
||||
bool use_hotplug_event_source;
|
||||
sPAPREventSource *event_sources;
|
||||
SpaprEventSource *event_sources;
|
||||
|
||||
/* ibm,client-architecture-support option negotiation */
|
||||
bool cas_reboot;
|
||||
bool cas_legacy_guest_workaround;
|
||||
sPAPROptionVector *ov5; /* QEMU-supported option vectors */
|
||||
sPAPROptionVector *ov5_cas; /* negotiated (via CAS) option vectors */
|
||||
SpaprOptionVector *ov5; /* QEMU-supported option vectors */
|
||||
SpaprOptionVector *ov5_cas; /* negotiated (via CAS) option vectors */
|
||||
uint32_t max_compat_pvr;
|
||||
|
||||
/* Migration state */
|
||||
@ -174,7 +183,7 @@ struct sPAPRMachineState {
|
||||
/* Pending DIMM unplug cache. It is populated when a LMB
|
||||
* unplug starts. It can be regenerated if a migration
|
||||
* occurs during the unplug process. */
|
||||
QTAILQ_HEAD(, sPAPRDIMMState) pending_dimm_unplugs;
|
||||
QTAILQ_HEAD(, SpaprDimmState) pending_dimm_unplugs;
|
||||
|
||||
/*< public >*/
|
||||
char *kvm_type;
|
||||
@ -183,12 +192,12 @@ struct sPAPRMachineState {
|
||||
|
||||
int32_t irq_map_nr;
|
||||
unsigned long *irq_map;
|
||||
sPAPRXive *xive;
|
||||
sPAPRIrq *irq;
|
||||
SpaprXive *xive;
|
||||
SpaprIrq *irq;
|
||||
qemu_irq *qirqs;
|
||||
|
||||
bool cmd_line_caps[SPAPR_CAP_NUM];
|
||||
sPAPRCapabilities def, eff, mig;
|
||||
SpaprCapabilities def, eff, mig;
|
||||
};
|
||||
|
||||
#define H_SUCCESS 0
|
||||
@ -337,9 +346,11 @@ struct sPAPRMachineState {
|
||||
#define H_CPU_CHAR_HON_BRANCH_HINTS PPC_BIT(5)
|
||||
#define H_CPU_CHAR_THR_RECONF_TRIG PPC_BIT(6)
|
||||
#define H_CPU_CHAR_CACHE_COUNT_DIS PPC_BIT(7)
|
||||
#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST PPC_BIT(9)
|
||||
#define H_CPU_BEHAV_FAVOUR_SECURITY PPC_BIT(0)
|
||||
#define H_CPU_BEHAV_L1D_FLUSH_PR PPC_BIT(1)
|
||||
#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR PPC_BIT(2)
|
||||
#define H_CPU_BEHAV_FLUSH_COUNT_CACHE PPC_BIT(5)
|
||||
|
||||
/* Each control block has to be on a 4K boundary */
|
||||
#define H_CB_ALIGNMENT 4096
|
||||
@ -492,16 +503,16 @@ struct sPAPRMachineState {
|
||||
#define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3)
|
||||
#define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT
|
||||
|
||||
typedef struct sPAPRDeviceTreeUpdateHeader {
|
||||
typedef struct SpaprDeviceTreeUpdateHeader {
|
||||
uint32_t version_id;
|
||||
} sPAPRDeviceTreeUpdateHeader;
|
||||
} SpaprDeviceTreeUpdateHeader;
|
||||
|
||||
#define hcall_dprintf(fmt, ...) \
|
||||
do { \
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt, __func__, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
|
||||
typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
|
||||
target_ulong opcode,
|
||||
target_ulong *args);
|
||||
|
||||
@ -655,16 +666,16 @@ static inline void rtas_st(target_ulong phys, int n, uint32_t val)
|
||||
stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val);
|
||||
}
|
||||
|
||||
typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm,
|
||||
typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
|
||||
uint32_t token,
|
||||
uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets);
|
||||
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm,
|
||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
|
||||
uint32_t token, uint32_t nargs, target_ulong args,
|
||||
uint32_t nret, target_ulong rets);
|
||||
void spapr_dt_rtas_tokens(void *fdt, int rtas);
|
||||
void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr);
|
||||
void spapr_load_rtas(SpaprMachineState *spapr, void *fdt, hwaddr addr);
|
||||
|
||||
#define SPAPR_TCE_PAGE_SHIFT 12
|
||||
#define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT)
|
||||
@ -691,17 +702,17 @@ static inline void spapr_dt_irq(uint32_t *intspec, int irq, bool is_lsi)
|
||||
intspec[1] = is_lsi ? cpu_to_be32(1) : 0;
|
||||
}
|
||||
|
||||
typedef struct sPAPRTCETable sPAPRTCETable;
|
||||
typedef struct SpaprTceTable SpaprTceTable;
|
||||
|
||||
#define TYPE_SPAPR_TCE_TABLE "spapr-tce-table"
|
||||
#define SPAPR_TCE_TABLE(obj) \
|
||||
OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE)
|
||||
OBJECT_CHECK(SpaprTceTable, (obj), TYPE_SPAPR_TCE_TABLE)
|
||||
|
||||
#define TYPE_SPAPR_IOMMU_MEMORY_REGION "spapr-iommu-memory-region"
|
||||
#define SPAPR_IOMMU_MEMORY_REGION(obj) \
|
||||
OBJECT_CHECK(IOMMUMemoryRegion, (obj), TYPE_SPAPR_IOMMU_MEMORY_REGION)
|
||||
|
||||
struct sPAPRTCETable {
|
||||
struct SpaprTceTable {
|
||||
DeviceState parent;
|
||||
uint32_t liobn;
|
||||
uint32_t nb_table;
|
||||
@ -712,76 +723,77 @@ struct sPAPRTCETable {
|
||||
uint64_t *mig_table;
|
||||
bool bypass;
|
||||
bool need_vfio;
|
||||
bool skipping_replay;
|
||||
int fd;
|
||||
MemoryRegion root;
|
||||
IOMMUMemoryRegion iommu;
|
||||
struct VIOsPAPRDevice *vdev; /* for @bypass migration compatibility only */
|
||||
QLIST_ENTRY(sPAPRTCETable) list;
|
||||
struct SpaprVioDevice *vdev; /* for @bypass migration compatibility only */
|
||||
QLIST_ENTRY(SpaprTceTable) list;
|
||||
};
|
||||
|
||||
sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn);
|
||||
SpaprTceTable *spapr_tce_find_by_liobn(target_ulong liobn);
|
||||
|
||||
struct sPAPREventLogEntry {
|
||||
struct SpaprEventLogEntry {
|
||||
uint32_t summary;
|
||||
uint32_t extended_length;
|
||||
void *extended_log;
|
||||
QTAILQ_ENTRY(sPAPREventLogEntry) next;
|
||||
QTAILQ_ENTRY(SpaprEventLogEntry) next;
|
||||
};
|
||||
|
||||
void spapr_events_init(sPAPRMachineState *sm);
|
||||
void spapr_dt_events(sPAPRMachineState *sm, void *fdt);
|
||||
int spapr_h_cas_compose_response(sPAPRMachineState *sm,
|
||||
void spapr_events_init(SpaprMachineState *sm);
|
||||
void spapr_dt_events(SpaprMachineState *sm, void *fdt);
|
||||
int spapr_h_cas_compose_response(SpaprMachineState *sm,
|
||||
target_ulong addr, target_ulong size,
|
||||
sPAPROptionVector *ov5_updates);
|
||||
void close_htab_fd(sPAPRMachineState *spapr);
|
||||
void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr);
|
||||
void spapr_free_hpt(sPAPRMachineState *spapr);
|
||||
sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
|
||||
void spapr_tce_table_enable(sPAPRTCETable *tcet,
|
||||
SpaprOptionVector *ov5_updates);
|
||||
void close_htab_fd(SpaprMachineState *spapr);
|
||||
void spapr_setup_hpt_and_vrma(SpaprMachineState *spapr);
|
||||
void spapr_free_hpt(SpaprMachineState *spapr);
|
||||
SpaprTceTable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn);
|
||||
void spapr_tce_table_enable(SpaprTceTable *tcet,
|
||||
uint32_t page_shift, uint64_t bus_offset,
|
||||
uint32_t nb_table);
|
||||
void spapr_tce_table_disable(sPAPRTCETable *tcet);
|
||||
void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio);
|
||||
void spapr_tce_table_disable(SpaprTceTable *tcet);
|
||||
void spapr_tce_set_need_vfio(SpaprTceTable *tcet, bool need_vfio);
|
||||
|
||||
MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
|
||||
MemoryRegion *spapr_tce_get_iommu(SpaprTceTable *tcet);
|
||||
int spapr_dma_dt(void *fdt, int node_off, const char *propname,
|
||||
uint32_t liobn, uint64_t window, uint32_t size);
|
||||
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
|
||||
sPAPRTCETable *tcet);
|
||||
SpaprTceTable *tcet);
|
||||
void spapr_pci_switch_vga(bool big_endian);
|
||||
void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc);
|
||||
void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc);
|
||||
void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_add_by_index(SpaprDrc *drc);
|
||||
void spapr_hotplug_req_remove_by_index(SpaprDrc *drc);
|
||||
void spapr_hotplug_req_add_by_count(SpaprDrcType drc_type,
|
||||
uint32_t count);
|
||||
void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_remove_by_count(SpaprDrcType drc_type,
|
||||
uint32_t count);
|
||||
void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_add_by_count_indexed(SpaprDrcType drc_type,
|
||||
uint32_t count, uint32_t index);
|
||||
void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type,
|
||||
void spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type,
|
||||
uint32_t count, uint32_t index);
|
||||
int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
|
||||
void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
|
||||
void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
|
||||
Error **errp);
|
||||
void spapr_clear_pending_events(sPAPRMachineState *spapr);
|
||||
int spapr_max_server_number(sPAPRMachineState *spapr);
|
||||
void spapr_clear_pending_events(SpaprMachineState *spapr);
|
||||
int spapr_max_server_number(SpaprMachineState *spapr);
|
||||
|
||||
/* DRC callbacks. */
|
||||
void spapr_core_release(DeviceState *dev);
|
||||
int spapr_core_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp);
|
||||
void spapr_lmb_release(DeviceState *dev);
|
||||
int spapr_lmb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp);
|
||||
void spapr_phb_release(DeviceState *dev);
|
||||
int spapr_phb_dt_populate(sPAPRDRConnector *drc, sPAPRMachineState *spapr,
|
||||
int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp);
|
||||
|
||||
void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns);
|
||||
int spapr_rtc_import_offset(sPAPRRTCState *rtc, int64_t legacy_offset);
|
||||
void spapr_rtc_read(SpaprRtcState *rtc, struct tm *tm, uint32_t *ns);
|
||||
int spapr_rtc_import_offset(SpaprRtcState *rtc, int64_t legacy_offset);
|
||||
|
||||
#define TYPE_SPAPR_RNG "spapr-rng"
|
||||
|
||||
#define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
|
||||
#define SPAPR_MEMORY_BLOCK_SIZE ((hwaddr)1 << 28) /* 256MB */
|
||||
|
||||
/*
|
||||
* This defines the maximum number of DIMM slots we can have for sPAPR
|
||||
@ -828,19 +840,21 @@ extern const VMStateDescription vmstate_spapr_cap_cfpc;
|
||||
extern const VMStateDescription vmstate_spapr_cap_sbbc;
|
||||
extern const VMStateDescription vmstate_spapr_cap_ibs;
|
||||
extern const VMStateDescription vmstate_spapr_cap_nested_kvm_hv;
|
||||
extern const VMStateDescription vmstate_spapr_cap_large_decr;
|
||||
extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
|
||||
|
||||
static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap)
|
||||
static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap)
|
||||
{
|
||||
return spapr->eff.caps[cap];
|
||||
}
|
||||
|
||||
void spapr_caps_init(sPAPRMachineState *spapr);
|
||||
void spapr_caps_apply(sPAPRMachineState *spapr);
|
||||
void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu);
|
||||
void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp);
|
||||
int spapr_caps_post_migration(sPAPRMachineState *spapr);
|
||||
void spapr_caps_init(SpaprMachineState *spapr);
|
||||
void spapr_caps_apply(SpaprMachineState *spapr);
|
||||
void spapr_caps_cpu_apply(SpaprMachineState *spapr, PowerPCCPU *cpu);
|
||||
void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp);
|
||||
int spapr_caps_post_migration(SpaprMachineState *spapr);
|
||||
|
||||
void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize,
|
||||
void spapr_check_pagesize(SpaprMachineState *spapr, hwaddr pagesize,
|
||||
Error **errp);
|
||||
/*
|
||||
* XIVE definitions
|
||||
|
@ -16,43 +16,43 @@
|
||||
|
||||
#define TYPE_SPAPR_CPU_CORE "spapr-cpu-core"
|
||||
#define SPAPR_CPU_CORE(obj) \
|
||||
OBJECT_CHECK(sPAPRCPUCore, (obj), TYPE_SPAPR_CPU_CORE)
|
||||
OBJECT_CHECK(SpaprCpuCore, (obj), TYPE_SPAPR_CPU_CORE)
|
||||
#define SPAPR_CPU_CORE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRCPUCoreClass, (klass), TYPE_SPAPR_CPU_CORE)
|
||||
OBJECT_CLASS_CHECK(SpaprCpuCoreClass, (klass), TYPE_SPAPR_CPU_CORE)
|
||||
#define SPAPR_CPU_CORE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRCPUCoreClass, (obj), TYPE_SPAPR_CPU_CORE)
|
||||
OBJECT_GET_CLASS(SpaprCpuCoreClass, (obj), TYPE_SPAPR_CPU_CORE)
|
||||
|
||||
#define SPAPR_CPU_CORE_TYPE_NAME(model) model "-" TYPE_SPAPR_CPU_CORE
|
||||
|
||||
typedef struct sPAPRCPUCore {
|
||||
typedef struct SpaprCpuCore {
|
||||
/*< private >*/
|
||||
CPUCore parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
PowerPCCPU **threads;
|
||||
int node_id;
|
||||
bool pre_3_0_migration; /* older machine don't know about sPAPRCPUState */
|
||||
} sPAPRCPUCore;
|
||||
bool pre_3_0_migration; /* older machine don't know about SpaprCpuState */
|
||||
} SpaprCpuCore;
|
||||
|
||||
typedef struct sPAPRCPUCoreClass {
|
||||
typedef struct SpaprCpuCoreClass {
|
||||
DeviceClass parent_class;
|
||||
const char *cpu_type;
|
||||
} sPAPRCPUCoreClass;
|
||||
} SpaprCpuCoreClass;
|
||||
|
||||
const char *spapr_get_cpu_core_type(const char *cpu_type);
|
||||
void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3);
|
||||
|
||||
typedef struct sPAPRCPUState {
|
||||
typedef struct SpaprCpuState {
|
||||
uint64_t vpa_addr;
|
||||
uint64_t slb_shadow_addr, slb_shadow_size;
|
||||
uint64_t dtl_addr, dtl_size;
|
||||
struct ICPState *icp;
|
||||
struct XiveTCTX *tctx;
|
||||
} sPAPRCPUState;
|
||||
} SpaprCpuState;
|
||||
|
||||
static inline sPAPRCPUState *spapr_cpu_state(PowerPCCPU *cpu)
|
||||
static inline SpaprCpuState *spapr_cpu_state(PowerPCCPU *cpu)
|
||||
{
|
||||
return (sPAPRCPUState *)cpu->machine_data;
|
||||
return (SpaprCpuState *)cpu->machine_data;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -22,65 +22,65 @@
|
||||
|
||||
#define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
|
||||
#define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DR_CONNECTOR)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DR_CONNECTOR)
|
||||
#define SPAPR_DR_CONNECTOR_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
|
||||
TYPE_SPAPR_DR_CONNECTOR)
|
||||
#define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
#define SPAPR_DR_CONNECTOR(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DR_CONNECTOR)
|
||||
|
||||
#define TYPE_SPAPR_DRC_PHYSICAL "spapr-drc-physical"
|
||||
#define SPAPR_DRC_PHYSICAL_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHYSICAL)
|
||||
#define SPAPR_DRC_PHYSICAL_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
|
||||
TYPE_SPAPR_DRC_PHYSICAL)
|
||||
#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(sPAPRDRCPhysical, (obj), \
|
||||
#define SPAPR_DRC_PHYSICAL(obj) OBJECT_CHECK(SpaprDrcPhysical, (obj), \
|
||||
TYPE_SPAPR_DRC_PHYSICAL)
|
||||
|
||||
#define TYPE_SPAPR_DRC_LOGICAL "spapr-drc-logical"
|
||||
#define SPAPR_DRC_LOGICAL_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LOGICAL)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LOGICAL)
|
||||
#define SPAPR_DRC_LOGICAL_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, \
|
||||
TYPE_SPAPR_DRC_LOGICAL)
|
||||
#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
#define SPAPR_DRC_LOGICAL(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DRC_LOGICAL)
|
||||
|
||||
#define TYPE_SPAPR_DRC_CPU "spapr-drc-cpu"
|
||||
#define SPAPR_DRC_CPU_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_CPU)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_CPU)
|
||||
#define SPAPR_DRC_CPU_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_CPU)
|
||||
#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_CPU)
|
||||
#define SPAPR_DRC_CPU(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DRC_CPU)
|
||||
|
||||
#define TYPE_SPAPR_DRC_PCI "spapr-drc-pci"
|
||||
#define SPAPR_DRC_PCI_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PCI)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PCI)
|
||||
#define SPAPR_DRC_PCI_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PCI)
|
||||
#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PCI)
|
||||
#define SPAPR_DRC_PCI(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DRC_PCI)
|
||||
|
||||
#define TYPE_SPAPR_DRC_LMB "spapr-drc-lmb"
|
||||
#define SPAPR_DRC_LMB_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_LMB)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_LMB)
|
||||
#define SPAPR_DRC_LMB_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_LMB)
|
||||
#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_LMB)
|
||||
#define SPAPR_DRC_LMB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DRC_LMB)
|
||||
|
||||
#define TYPE_SPAPR_DRC_PHB "spapr-drc-phb"
|
||||
#define SPAPR_DRC_PHB_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(sPAPRDRConnectorClass, obj, TYPE_SPAPR_DRC_PHB)
|
||||
OBJECT_GET_CLASS(SpaprDrcClass, obj, TYPE_SPAPR_DRC_PHB)
|
||||
#define SPAPR_DRC_PHB_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(sPAPRDRConnectorClass, klass, TYPE_SPAPR_DRC_PHB)
|
||||
#define SPAPR_DRC_PHB(obj) OBJECT_CHECK(sPAPRDRConnector, (obj), \
|
||||
OBJECT_CLASS_CHECK(SpaprDrcClass, klass, TYPE_SPAPR_DRC_PHB)
|
||||
#define SPAPR_DRC_PHB(obj) OBJECT_CHECK(SpaprDrc, (obj), \
|
||||
TYPE_SPAPR_DRC_PHB)
|
||||
|
||||
/*
|
||||
* Various hotplug types managed by sPAPRDRConnector
|
||||
* Various hotplug types managed by SpaprDrc
|
||||
*
|
||||
* these are somewhat arbitrary, but to make things easier
|
||||
* when generating DRC indexes later we've aligned the bit
|
||||
@ -96,7 +96,7 @@ typedef enum {
|
||||
SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO = 3,
|
||||
SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI = 4,
|
||||
SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB = 8,
|
||||
} sPAPRDRConnectorTypeShift;
|
||||
} SpaprDrcTypeShift;
|
||||
|
||||
typedef enum {
|
||||
SPAPR_DR_CONNECTOR_TYPE_ANY = ~0,
|
||||
@ -105,7 +105,7 @@ typedef enum {
|
||||
SPAPR_DR_CONNECTOR_TYPE_VIO = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_VIO,
|
||||
SPAPR_DR_CONNECTOR_TYPE_PCI = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI,
|
||||
SPAPR_DR_CONNECTOR_TYPE_LMB = 1 << SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB,
|
||||
} sPAPRDRConnectorType;
|
||||
} SpaprDrcType;
|
||||
|
||||
/*
|
||||
* set via set-indicator RTAS calls
|
||||
@ -117,7 +117,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
SPAPR_DR_ISOLATION_STATE_ISOLATED = 0,
|
||||
SPAPR_DR_ISOLATION_STATE_UNISOLATED = 1
|
||||
} sPAPRDRIsolationState;
|
||||
} SpaprDRIsolationState;
|
||||
|
||||
/*
|
||||
* set via set-indicator RTAS calls
|
||||
@ -133,7 +133,7 @@ typedef enum {
|
||||
SPAPR_DR_ALLOCATION_STATE_USABLE = 1,
|
||||
SPAPR_DR_ALLOCATION_STATE_EXCHANGE = 2,
|
||||
SPAPR_DR_ALLOCATION_STATE_RECOVER = 3
|
||||
} sPAPRDRAllocationState;
|
||||
} SpaprDRAllocationState;
|
||||
|
||||
/*
|
||||
* DR-indicator (LED/visual indicator)
|
||||
@ -152,7 +152,7 @@ typedef enum {
|
||||
SPAPR_DR_INDICATOR_ACTIVE = 1,
|
||||
SPAPR_DR_INDICATOR_IDENTIFY = 2,
|
||||
SPAPR_DR_INDICATOR_ACTION = 3,
|
||||
} sPAPRDRIndicatorState;
|
||||
} SpaprDRIndicatorState;
|
||||
|
||||
/*
|
||||
* returned via get-sensor-state RTAS calls
|
||||
@ -170,7 +170,7 @@ typedef enum {
|
||||
SPAPR_DR_ENTITY_SENSE_UNUSABLE = 2,
|
||||
SPAPR_DR_ENTITY_SENSE_EXCHANGE = 3,
|
||||
SPAPR_DR_ENTITY_SENSE_RECOVER = 4,
|
||||
} sPAPRDREntitySense;
|
||||
} SpaprDREntitySense;
|
||||
|
||||
typedef enum {
|
||||
SPAPR_DR_CC_RESPONSE_NEXT_SIB = 1, /* currently unused */
|
||||
@ -181,7 +181,7 @@ typedef enum {
|
||||
SPAPR_DR_CC_RESPONSE_ERROR = -1,
|
||||
SPAPR_DR_CC_RESPONSE_CONTINUE = -2,
|
||||
SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE = -9003,
|
||||
} sPAPRDRCCResponse;
|
||||
} SpaprDRCCResponse;
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
@ -199,9 +199,9 @@ typedef enum {
|
||||
SPAPR_DRC_STATE_PHYSICAL_POWERON = 6,
|
||||
SPAPR_DRC_STATE_PHYSICAL_UNISOLATE = 7,
|
||||
SPAPR_DRC_STATE_PHYSICAL_CONFIGURED = 8,
|
||||
} sPAPRDRCState;
|
||||
} SpaprDrcState;
|
||||
|
||||
typedef struct sPAPRDRConnector {
|
||||
typedef struct SpaprDrc {
|
||||
/*< private >*/
|
||||
DeviceState parent;
|
||||
|
||||
@ -220,60 +220,60 @@ typedef struct sPAPRDRConnector {
|
||||
bool unplug_requested;
|
||||
void *fdt;
|
||||
int fdt_start_offset;
|
||||
} sPAPRDRConnector;
|
||||
} SpaprDrc;
|
||||
|
||||
struct sPAPRMachineState;
|
||||
struct SpaprMachineState;
|
||||
|
||||
typedef struct sPAPRDRConnectorClass {
|
||||
typedef struct SpaprDrcClass {
|
||||
/*< private >*/
|
||||
DeviceClass parent;
|
||||
sPAPRDRCState empty_state;
|
||||
sPAPRDRCState ready_state;
|
||||
SpaprDrcState empty_state;
|
||||
SpaprDrcState ready_state;
|
||||
|
||||
/*< public >*/
|
||||
sPAPRDRConnectorTypeShift typeshift;
|
||||
SpaprDrcTypeShift typeshift;
|
||||
const char *typename; /* used in device tree, PAPR 13.5.2.6 & C.6.1 */
|
||||
const char *drc_name_prefix; /* used other places in device tree */
|
||||
|
||||
sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
|
||||
uint32_t (*isolate)(sPAPRDRConnector *drc);
|
||||
uint32_t (*unisolate)(sPAPRDRConnector *drc);
|
||||
SpaprDREntitySense (*dr_entity_sense)(SpaprDrc *drc);
|
||||
uint32_t (*isolate)(SpaprDrc *drc);
|
||||
uint32_t (*unisolate)(SpaprDrc *drc);
|
||||
void (*release)(DeviceState *dev);
|
||||
|
||||
int (*dt_populate)(sPAPRDRConnector *drc, struct sPAPRMachineState *spapr,
|
||||
int (*dt_populate)(SpaprDrc *drc, struct SpaprMachineState *spapr,
|
||||
void *fdt, int *fdt_start_offset, Error **errp);
|
||||
} sPAPRDRConnectorClass;
|
||||
} SpaprDrcClass;
|
||||
|
||||
typedef struct sPAPRDRCPhysical {
|
||||
typedef struct SpaprDrcPhysical {
|
||||
/*< private >*/
|
||||
sPAPRDRConnector parent;
|
||||
SpaprDrc parent;
|
||||
|
||||
/* DR-indicator */
|
||||
uint32_t dr_indicator;
|
||||
} sPAPRDRCPhysical;
|
||||
} SpaprDrcPhysical;
|
||||
|
||||
static inline bool spapr_drc_hotplugged(DeviceState *dev)
|
||||
{
|
||||
return dev->hotplugged && !runstate_check(RUN_STATE_INMIGRATE);
|
||||
}
|
||||
|
||||
void spapr_drc_reset(sPAPRDRConnector *drc);
|
||||
void spapr_drc_reset(SpaprDrc *drc);
|
||||
|
||||
uint32_t spapr_drc_index(sPAPRDRConnector *drc);
|
||||
sPAPRDRConnectorType spapr_drc_type(sPAPRDRConnector *drc);
|
||||
uint32_t spapr_drc_index(SpaprDrc *drc);
|
||||
SpaprDrcType spapr_drc_type(SpaprDrc *drc);
|
||||
|
||||
sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
|
||||
SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
|
||||
uint32_t id);
|
||||
sPAPRDRConnector *spapr_drc_by_index(uint32_t index);
|
||||
sPAPRDRConnector *spapr_drc_by_id(const char *type, uint32_t id);
|
||||
SpaprDrc *spapr_drc_by_index(uint32_t index);
|
||||
SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id);
|
||||
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
||||
uint32_t drc_type_mask);
|
||||
|
||||
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
|
||||
void spapr_drc_detach(sPAPRDRConnector *drc);
|
||||
void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp);
|
||||
void spapr_drc_detach(SpaprDrc *drc);
|
||||
bool spapr_drc_needed(void *opaque);
|
||||
|
||||
static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
|
||||
static inline bool spapr_drc_unplug_requested(SpaprDrc *drc)
|
||||
{
|
||||
return drc->unplug_requested;
|
||||
}
|
||||
|
@ -22,51 +22,51 @@
|
||||
#define SPAPR_IRQ_MSI 0x1300 /* Offset of the dynamic range covered
|
||||
* by the bitmap allocator */
|
||||
|
||||
typedef struct sPAPRMachineState sPAPRMachineState;
|
||||
typedef struct SpaprMachineState SpaprMachineState;
|
||||
|
||||
void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis);
|
||||
int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align,
|
||||
void spapr_irq_msi_init(SpaprMachineState *spapr, uint32_t nr_msis);
|
||||
int spapr_irq_msi_alloc(SpaprMachineState *spapr, uint32_t num, bool align,
|
||||
Error **errp);
|
||||
void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num);
|
||||
void spapr_irq_msi_reset(sPAPRMachineState *spapr);
|
||||
void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num);
|
||||
void spapr_irq_msi_reset(SpaprMachineState *spapr);
|
||||
|
||||
typedef struct sPAPRIrq {
|
||||
typedef struct SpaprIrq {
|
||||
uint32_t nr_irqs;
|
||||
uint32_t nr_msis;
|
||||
uint8_t ov5;
|
||||
|
||||
void (*init)(sPAPRMachineState *spapr, int nr_irqs, Error **errp);
|
||||
int (*claim)(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
|
||||
void (*free)(sPAPRMachineState *spapr, int irq, int num);
|
||||
qemu_irq (*qirq)(sPAPRMachineState *spapr, int irq);
|
||||
void (*print_info)(sPAPRMachineState *spapr, Monitor *mon);
|
||||
void (*dt_populate)(sPAPRMachineState *spapr, uint32_t nr_servers,
|
||||
void (*init)(SpaprMachineState *spapr, int nr_irqs, Error **errp);
|
||||
int (*claim)(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
|
||||
void (*free)(SpaprMachineState *spapr, int irq, int num);
|
||||
qemu_irq (*qirq)(SpaprMachineState *spapr, int irq);
|
||||
void (*print_info)(SpaprMachineState *spapr, Monitor *mon);
|
||||
void (*dt_populate)(SpaprMachineState *spapr, uint32_t nr_servers,
|
||||
void *fdt, uint32_t phandle);
|
||||
void (*cpu_intc_create)(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
||||
void (*cpu_intc_create)(SpaprMachineState *spapr, PowerPCCPU *cpu,
|
||||
Error **errp);
|
||||
int (*post_load)(sPAPRMachineState *spapr, int version_id);
|
||||
void (*reset)(sPAPRMachineState *spapr, Error **errp);
|
||||
int (*post_load)(SpaprMachineState *spapr, int version_id);
|
||||
void (*reset)(SpaprMachineState *spapr, Error **errp);
|
||||
void (*set_irq)(void *opaque, int srcno, int val);
|
||||
const char *(*get_nodename)(sPAPRMachineState *spapr);
|
||||
} sPAPRIrq;
|
||||
const char *(*get_nodename)(SpaprMachineState *spapr);
|
||||
} SpaprIrq;
|
||||
|
||||
extern sPAPRIrq spapr_irq_xics;
|
||||
extern sPAPRIrq spapr_irq_xics_legacy;
|
||||
extern sPAPRIrq spapr_irq_xive;
|
||||
extern sPAPRIrq spapr_irq_dual;
|
||||
extern SpaprIrq spapr_irq_xics;
|
||||
extern SpaprIrq spapr_irq_xics_legacy;
|
||||
extern SpaprIrq spapr_irq_xive;
|
||||
extern SpaprIrq spapr_irq_dual;
|
||||
|
||||
void spapr_irq_init(sPAPRMachineState *spapr, Error **errp);
|
||||
int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp);
|
||||
void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num);
|
||||
qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq);
|
||||
int spapr_irq_post_load(sPAPRMachineState *spapr, int version_id);
|
||||
void spapr_irq_reset(sPAPRMachineState *spapr, Error **errp);
|
||||
int spapr_irq_get_phandle(sPAPRMachineState *spapr, void *fdt, Error **errp);
|
||||
void spapr_irq_init(SpaprMachineState *spapr, Error **errp);
|
||||
int spapr_irq_claim(SpaprMachineState *spapr, int irq, bool lsi, Error **errp);
|
||||
void spapr_irq_free(SpaprMachineState *spapr, int irq, int num);
|
||||
qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq);
|
||||
int spapr_irq_post_load(SpaprMachineState *spapr, int version_id);
|
||||
void spapr_irq_reset(SpaprMachineState *spapr, Error **errp);
|
||||
int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp);
|
||||
|
||||
/*
|
||||
* XICS legacy routines
|
||||
*/
|
||||
int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp);
|
||||
int spapr_irq_find(SpaprMachineState *spapr, int num, bool align, Error **errp);
|
||||
#define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp)
|
||||
|
||||
#endif
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "cpu.h"
|
||||
#include "migration/vmstate.h"
|
||||
|
||||
typedef struct sPAPROptionVector sPAPROptionVector;
|
||||
typedef struct SpaprOptionVector SpaprOptionVector;
|
||||
|
||||
#define OV_BIT(byte, bit) ((byte - 1) * BITS_PER_BYTE + bit)
|
||||
|
||||
@ -61,21 +61,21 @@ typedef struct sPAPROptionVector sPAPROptionVector;
|
||||
#define OV5_MMU_RADIX_GTSE OV_BIT(26, 1) /* Radix GTSE */
|
||||
|
||||
/* interfaces */
|
||||
sPAPROptionVector *spapr_ovec_new(void);
|
||||
sPAPROptionVector *spapr_ovec_clone(sPAPROptionVector *ov_orig);
|
||||
void spapr_ovec_intersect(sPAPROptionVector *ov,
|
||||
sPAPROptionVector *ov1,
|
||||
sPAPROptionVector *ov2);
|
||||
bool spapr_ovec_diff(sPAPROptionVector *ov,
|
||||
sPAPROptionVector *ov_old,
|
||||
sPAPROptionVector *ov_new);
|
||||
void spapr_ovec_cleanup(sPAPROptionVector *ov);
|
||||
void spapr_ovec_set(sPAPROptionVector *ov, long bitnr);
|
||||
void spapr_ovec_clear(sPAPROptionVector *ov, long bitnr);
|
||||
bool spapr_ovec_test(sPAPROptionVector *ov, long bitnr);
|
||||
sPAPROptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
|
||||
SpaprOptionVector *spapr_ovec_new(void);
|
||||
SpaprOptionVector *spapr_ovec_clone(SpaprOptionVector *ov_orig);
|
||||
void spapr_ovec_intersect(SpaprOptionVector *ov,
|
||||
SpaprOptionVector *ov1,
|
||||
SpaprOptionVector *ov2);
|
||||
bool spapr_ovec_diff(SpaprOptionVector *ov,
|
||||
SpaprOptionVector *ov_old,
|
||||
SpaprOptionVector *ov_new);
|
||||
void spapr_ovec_cleanup(SpaprOptionVector *ov);
|
||||
void spapr_ovec_set(SpaprOptionVector *ov, long bitnr);
|
||||
void spapr_ovec_clear(SpaprOptionVector *ov, long bitnr);
|
||||
bool spapr_ovec_test(SpaprOptionVector *ov, long bitnr);
|
||||
SpaprOptionVector *spapr_ovec_parse_vector(target_ulong table_addr, int vector);
|
||||
int spapr_ovec_populate_dt(void *fdt, int fdt_offset,
|
||||
sPAPROptionVector *ov, const char *name);
|
||||
SpaprOptionVector *ov, const char *name);
|
||||
|
||||
/* migration */
|
||||
extern const VMStateDescription vmstate_spapr_ovec;
|
||||
|
@ -26,91 +26,91 @@
|
||||
|
||||
#define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
|
||||
#define VIO_SPAPR_DEVICE(obj) \
|
||||
OBJECT_CHECK(VIOsPAPRDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
|
||||
OBJECT_CHECK(SpaprVioDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
|
||||
#define VIO_SPAPR_DEVICE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(VIOsPAPRDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
|
||||
OBJECT_CLASS_CHECK(SpaprVioDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
|
||||
#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
|
||||
OBJECT_GET_CLASS(SpaprVioDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
|
||||
|
||||
#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
|
||||
#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
|
||||
#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(SpaprVioBus, (obj), TYPE_SPAPR_VIO_BUS)
|
||||
|
||||
#define TYPE_SPAPR_VIO_BRIDGE "spapr-vio-bridge"
|
||||
|
||||
typedef struct VIOsPAPR_CRQ {
|
||||
typedef struct SpaprVioCrq {
|
||||
uint64_t qladdr;
|
||||
uint32_t qsize;
|
||||
uint32_t qnext;
|
||||
int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
|
||||
} VIOsPAPR_CRQ;
|
||||
int(*SendFunc)(struct SpaprVioDevice *vdev, uint8_t *crq);
|
||||
} SpaprVioCrq;
|
||||
|
||||
typedef struct VIOsPAPRDevice VIOsPAPRDevice;
|
||||
typedef struct VIOsPAPRBus VIOsPAPRBus;
|
||||
typedef struct SpaprVioDevice SpaprVioDevice;
|
||||
typedef struct SpaprVioBus SpaprVioBus;
|
||||
|
||||
typedef struct VIOsPAPRDeviceClass {
|
||||
typedef struct SpaprVioDeviceClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
const char *dt_name, *dt_type, *dt_compatible;
|
||||
target_ulong signal_mask;
|
||||
uint32_t rtce_window_size;
|
||||
void (*realize)(VIOsPAPRDevice *dev, Error **errp);
|
||||
void (*reset)(VIOsPAPRDevice *dev);
|
||||
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
|
||||
} VIOsPAPRDeviceClass;
|
||||
void (*realize)(SpaprVioDevice *dev, Error **errp);
|
||||
void (*reset)(SpaprVioDevice *dev);
|
||||
int (*devnode)(SpaprVioDevice *dev, void *fdt, int node_off);
|
||||
} SpaprVioDeviceClass;
|
||||
|
||||
struct VIOsPAPRDevice {
|
||||
struct SpaprVioDevice {
|
||||
DeviceState qdev;
|
||||
uint32_t reg;
|
||||
uint32_t irq;
|
||||
uint64_t signal_state;
|
||||
VIOsPAPR_CRQ crq;
|
||||
SpaprVioCrq crq;
|
||||
AddressSpace as;
|
||||
MemoryRegion mrroot;
|
||||
MemoryRegion mrbypass;
|
||||
sPAPRTCETable *tcet;
|
||||
SpaprTceTable *tcet;
|
||||
};
|
||||
|
||||
#define DEFINE_SPAPR_PROPERTIES(type, field) \
|
||||
DEFINE_PROP_UINT32("reg", type, field.reg, -1)
|
||||
|
||||
struct VIOsPAPRBus {
|
||||
struct SpaprVioBus {
|
||||
BusState bus;
|
||||
uint32_t next_reg;
|
||||
};
|
||||
|
||||
extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
||||
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
||||
void spapr_dt_vdevice(VIOsPAPRBus *bus, void *fdt);
|
||||
extern gchar *spapr_vio_stdout_path(VIOsPAPRBus *bus);
|
||||
extern SpaprVioBus *spapr_vio_bus_init(void);
|
||||
extern SpaprVioDevice *spapr_vio_find_by_reg(SpaprVioBus *bus, uint32_t reg);
|
||||
void spapr_dt_vdevice(SpaprVioBus *bus, void *fdt);
|
||||
extern gchar *spapr_vio_stdout_path(SpaprVioBus *bus);
|
||||
|
||||
static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
|
||||
static inline qemu_irq spapr_vio_qirq(SpaprVioDevice *dev)
|
||||
{
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
|
||||
return spapr_qirq(spapr, dev->irq);
|
||||
}
|
||||
|
||||
static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
|
||||
static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr,
|
||||
uint32_t size, DMADirection dir)
|
||||
{
|
||||
return dma_memory_valid(&dev->as, taddr, size, dir);
|
||||
}
|
||||
|
||||
static inline int spapr_vio_dma_read(VIOsPAPRDevice *dev, uint64_t taddr,
|
||||
static inline int spapr_vio_dma_read(SpaprVioDevice *dev, uint64_t taddr,
|
||||
void *buf, uint32_t size)
|
||||
{
|
||||
return (dma_memory_read(&dev->as, taddr, buf, size) != 0) ?
|
||||
H_DEST_PARM : H_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int spapr_vio_dma_write(VIOsPAPRDevice *dev, uint64_t taddr,
|
||||
static inline int spapr_vio_dma_write(SpaprVioDevice *dev, uint64_t taddr,
|
||||
const void *buf, uint32_t size)
|
||||
{
|
||||
return (dma_memory_write(&dev->as, taddr, buf, size) != 0) ?
|
||||
H_DEST_PARM : H_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
|
||||
static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr,
|
||||
uint8_t c, uint32_t size)
|
||||
{
|
||||
return (dma_memory_set(&dev->as, taddr, c, size) != 0) ?
|
||||
@ -123,21 +123,21 @@ static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
|
||||
#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val)))
|
||||
#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr)))
|
||||
|
||||
int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
|
||||
int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq);
|
||||
|
||||
VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg);
|
||||
void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
|
||||
void spapr_vty_create(VIOsPAPRBus *bus, Chardev *chardev);
|
||||
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd);
|
||||
void spapr_vscsi_create(VIOsPAPRBus *bus);
|
||||
SpaprVioDevice *vty_lookup(SpaprMachineState *spapr, target_ulong reg);
|
||||
void vty_putchars(SpaprVioDevice *sdev, uint8_t *buf, int len);
|
||||
void spapr_vty_create(SpaprVioBus *bus, Chardev *chardev);
|
||||
void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd);
|
||||
void spapr_vscsi_create(SpaprVioBus *bus);
|
||||
|
||||
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
|
||||
SpaprVioDevice *spapr_vty_get_default(SpaprVioBus *bus);
|
||||
|
||||
extern const VMStateDescription vmstate_spapr_vio;
|
||||
|
||||
#define VMSTATE_SPAPR_VIO(_f, _s) \
|
||||
VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, VIOsPAPRDevice)
|
||||
VMSTATE_STRUCT(_f, _s, 0, vmstate_spapr_vio, SpaprVioDevice)
|
||||
|
||||
void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass);
|
||||
void spapr_vio_set_bypass(SpaprVioDevice *dev, bool bypass);
|
||||
|
||||
#endif /* HW_SPAPR_VIO_H */
|
||||
|
@ -13,9 +13,9 @@
|
||||
#include "hw/ppc/xive.h"
|
||||
|
||||
#define TYPE_SPAPR_XIVE "spapr-xive"
|
||||
#define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE)
|
||||
#define SPAPR_XIVE(obj) OBJECT_CHECK(SpaprXive, (obj), TYPE_SPAPR_XIVE)
|
||||
|
||||
typedef struct sPAPRXive {
|
||||
typedef struct SpaprXive {
|
||||
XiveRouter parent;
|
||||
|
||||
/* Internal interrupt source for IPIs and virtual devices */
|
||||
@ -38,16 +38,16 @@ typedef struct sPAPRXive {
|
||||
/* TIMA mapping address */
|
||||
hwaddr tm_base;
|
||||
MemoryRegion tm_mmio;
|
||||
} sPAPRXive;
|
||||
} SpaprXive;
|
||||
|
||||
bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi);
|
||||
bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn);
|
||||
void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon);
|
||||
bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi);
|
||||
bool spapr_xive_irq_free(SpaprXive *xive, uint32_t lisn);
|
||||
void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon);
|
||||
|
||||
void spapr_xive_hcall_init(sPAPRMachineState *spapr);
|
||||
void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
void spapr_xive_hcall_init(SpaprMachineState *spapr);
|
||||
void spapr_dt_xive(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle);
|
||||
void spapr_xive_set_tctx_os_cam(XiveTCTX *tctx);
|
||||
void spapr_xive_mmio_set_enabled(sPAPRXive *xive, bool enable);
|
||||
void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable);
|
||||
|
||||
#endif /* PPC_SPAPR_XIVE_H */
|
||||
|
@ -31,9 +31,9 @@
|
||||
|
||||
#define XICS_NODENAME "interrupt-controller"
|
||||
|
||||
void spapr_dt_xics(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
|
||||
uint32_t phandle);
|
||||
int xics_kvm_init(sPAPRMachineState *spapr, Error **errp);
|
||||
void xics_spapr_init(sPAPRMachineState *spapr);
|
||||
int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
|
||||
void xics_spapr_init(SpaprMachineState *spapr);
|
||||
|
||||
#endif /* XICS_SPAPR_H */
|
||||
|
@ -364,6 +364,7 @@ int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
XiveNVT *nvt, uint8_t word_number);
|
||||
XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
|
||||
void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
|
||||
|
||||
/*
|
||||
* XIVE END ESBs
|
||||
@ -410,6 +411,9 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon);
|
||||
#define XIVE_TM_USER_PAGE 0x3
|
||||
|
||||
extern const MemoryRegionOps xive_tm_ops;
|
||||
void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
|
||||
unsigned size);
|
||||
uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
|
||||
|
||||
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
|
||||
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
|
||||
|
@ -189,6 +189,8 @@ int vfio_get_region_info(VFIODevice *vbasedev, int index,
|
||||
int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
|
||||
uint32_t subtype, struct vfio_region_info **info);
|
||||
bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
|
||||
struct vfio_info_cap_header *
|
||||
vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id);
|
||||
#endif
|
||||
extern const MemoryListener vfio_prereg_listener;
|
||||
|
||||
|
Binary file not shown.
@ -1 +1 @@
|
||||
Subproject commit d85ca029f257b53a96da6c2fb421e78a003a9943
|
||||
Subproject commit d3689267f92c5956e09cc7d1baa4700141662bff
|
@ -190,6 +190,7 @@ typedef struct PowerPCCPUClass {
|
||||
#endif
|
||||
const PPCHash64Options *hash64_opts;
|
||||
struct ppc_radix_page_info *radix_page_info;
|
||||
uint32_t lrg_decr_bits;
|
||||
void (*init_proc)(CPUPPCState *env);
|
||||
int (*check_pow)(CPUPPCState *env);
|
||||
int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
|
||||
|
@ -1321,10 +1321,10 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env);
|
||||
void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value);
|
||||
void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value);
|
||||
bool ppc_decr_clear_on_delivery(CPUPPCState *env);
|
||||
uint32_t cpu_ppc_load_decr (CPUPPCState *env);
|
||||
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
|
||||
uint32_t cpu_ppc_load_hdecr (CPUPPCState *env);
|
||||
void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value);
|
||||
target_ulong cpu_ppc_load_decr(CPUPPCState *env);
|
||||
void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
|
||||
target_ulong cpu_ppc_load_hdecr(CPUPPCState *env);
|
||||
void cpu_ppc_store_hdecr(CPUPPCState *env, target_ulong value);
|
||||
uint64_t cpu_ppc_load_purr (CPUPPCState *env);
|
||||
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
|
||||
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
|
||||
@ -2563,19 +2563,64 @@ static inline bool lsw_reg_in_range(int start, int nregs, int rx)
|
||||
}
|
||||
|
||||
/* Accessors for FP, VMX and VSX registers */
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
#define VsrB(i) u8[i]
|
||||
#define VsrSB(i) s8[i]
|
||||
#define VsrH(i) u16[i]
|
||||
#define VsrSH(i) s16[i]
|
||||
#define VsrW(i) u32[i]
|
||||
#define VsrSW(i) s32[i]
|
||||
#define VsrD(i) u64[i]
|
||||
#define VsrSD(i) s64[i]
|
||||
#else
|
||||
#define VsrB(i) u8[15 - (i)]
|
||||
#define VsrSB(i) s8[15 - (i)]
|
||||
#define VsrH(i) u16[7 - (i)]
|
||||
#define VsrSH(i) s16[7 - (i)]
|
||||
#define VsrW(i) u32[3 - (i)]
|
||||
#define VsrSW(i) s32[3 - (i)]
|
||||
#define VsrD(i) u64[1 - (i)]
|
||||
#define VsrSD(i) s64[1 - (i)]
|
||||
#endif
|
||||
|
||||
static inline int vsr64_offset(int i, bool high)
|
||||
{
|
||||
return offsetof(CPUPPCState, vsr[i].VsrD(high ? 0 : 1));
|
||||
}
|
||||
|
||||
static inline int vsr_full_offset(int i)
|
||||
{
|
||||
return offsetof(CPUPPCState, vsr[i].u64[0]);
|
||||
}
|
||||
|
||||
static inline int fpr_offset(int i)
|
||||
{
|
||||
return vsr64_offset(i, true);
|
||||
}
|
||||
|
||||
static inline uint64_t *cpu_fpr_ptr(CPUPPCState *env, int i)
|
||||
{
|
||||
return &env->vsr[i].u64[0];
|
||||
return (uint64_t *)((uintptr_t)env + fpr_offset(i));
|
||||
}
|
||||
|
||||
static inline uint64_t *cpu_vsrl_ptr(CPUPPCState *env, int i)
|
||||
{
|
||||
return &env->vsr[i].u64[1];
|
||||
return (uint64_t *)((uintptr_t)env + vsr64_offset(i, false));
|
||||
}
|
||||
|
||||
static inline long avr64_offset(int i, bool high)
|
||||
{
|
||||
return vsr64_offset(i + 32, high);
|
||||
}
|
||||
|
||||
static inline int avr_full_offset(int i)
|
||||
{
|
||||
return vsr_full_offset(i + 32);
|
||||
}
|
||||
|
||||
static inline ppc_avr_t *cpu_avr_ptr(CPUPPCState *env, int i)
|
||||
{
|
||||
return &env->vsr[32 + i];
|
||||
return (ppc_avr_t *)((uintptr_t)env + avr_full_offset(i));
|
||||
}
|
||||
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
|
||||
|
@ -107,6 +107,24 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
|
||||
return POWERPC_EXCP_RESET;
|
||||
}
|
||||
|
||||
static uint64_t ppc_excp_vector_offset(CPUState *cs, int ail)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
|
||||
switch (ail) {
|
||||
case AIL_0001_8000:
|
||||
offset = 0x18000;
|
||||
break;
|
||||
case AIL_C000_0000_0000_4000:
|
||||
offset = 0xc000000000004000ull;
|
||||
break;
|
||||
default:
|
||||
cpu_abort(cs, "Invalid AIL combination %d\n", ail);
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Note that this function should be greatly optimized
|
||||
* when called with a constant excp, from ppc_hw_interrupt
|
||||
@ -708,17 +726,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
/* Handle AIL */
|
||||
if (ail) {
|
||||
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
|
||||
switch(ail) {
|
||||
case AIL_0001_8000:
|
||||
vector |= 0x18000;
|
||||
break;
|
||||
case AIL_C000_0000_0000_4000:
|
||||
vector |= 0xc000000000004000ull;
|
||||
break;
|
||||
default:
|
||||
cpu_abort(cs, "Invalid AIL combination %d\n", ail);
|
||||
break;
|
||||
}
|
||||
vector |= ppc_excp_vector_offset(cs, ail);
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
|
@ -204,35 +204,16 @@ EXTRACT_HELPER(IMM8, 11, 8);
|
||||
EXTRACT_HELPER(DCMX, 16, 7);
|
||||
EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
|
||||
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
#define VsrB(i) u8[i]
|
||||
#define VsrSB(i) s8[i]
|
||||
#define VsrH(i) u16[i]
|
||||
#define VsrSH(i) s16[i]
|
||||
#define VsrW(i) u32[i]
|
||||
#define VsrSW(i) s32[i]
|
||||
#define VsrD(i) u64[i]
|
||||
#define VsrSD(i) s64[i]
|
||||
#else
|
||||
#define VsrB(i) u8[15 - (i)]
|
||||
#define VsrSB(i) s8[15 - (i)]
|
||||
#define VsrH(i) u16[7 - (i)]
|
||||
#define VsrSH(i) s16[7 - (i)]
|
||||
#define VsrW(i) u32[3 - (i)]
|
||||
#define VsrSW(i) s32[3 - (i)]
|
||||
#define VsrD(i) u64[1 - (i)]
|
||||
#define VsrSD(i) s64[1 - (i)]
|
||||
#endif
|
||||
static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
|
||||
{
|
||||
vsr->VsrD(0) = env->vsr[n].u64[0];
|
||||
vsr->VsrD(1) = env->vsr[n].u64[1];
|
||||
vsr->VsrD(0) = env->vsr[n].VsrD(0);
|
||||
vsr->VsrD(1) = env->vsr[n].VsrD(1);
|
||||
}
|
||||
|
||||
static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
|
||||
{
|
||||
env->vsr[n].u64[0] = vsr->VsrD(0);
|
||||
env->vsr[n].u64[1] = vsr->VsrD(1);
|
||||
env->vsr[n].VsrD(0) = vsr->VsrD(0);
|
||||
env->vsr[n].VsrD(1) = vsr->VsrD(1);
|
||||
}
|
||||
|
||||
void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
|
||||
|
208
target/ppc/kvm.c
208
target/ppc/kvm.c
@ -90,7 +90,9 @@ static int cap_ppc_pvr_compat;
|
||||
static int cap_ppc_safe_cache;
|
||||
static int cap_ppc_safe_bounds_check;
|
||||
static int cap_ppc_safe_indirect_branch;
|
||||
static int cap_ppc_count_cache_flush_assist;
|
||||
static int cap_ppc_nested_kvm_hv;
|
||||
static int cap_large_decr;
|
||||
|
||||
static uint32_t debug_inst_opcode;
|
||||
|
||||
@ -124,6 +126,7 @@ static bool kvmppc_is_pr(KVMState *ks)
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(MachineState *ms);
|
||||
static void kvmppc_get_cpu_characteristics(KVMState *s);
|
||||
static int kvmppc_get_dec_bits(void);
|
||||
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
@ -151,6 +154,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
|
||||
kvmppc_get_cpu_characteristics(s);
|
||||
cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV);
|
||||
cap_large_decr = kvmppc_get_dec_bits();
|
||||
/*
|
||||
* Note: setting it to false because there is not such capability
|
||||
* in KVM at this moment.
|
||||
@ -752,7 +756,7 @@ static int kvm_get_fp(CPUState *cs)
|
||||
static int kvm_get_vpa(CPUState *cs)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
struct kvm_one_reg reg;
|
||||
int ret;
|
||||
|
||||
@ -792,7 +796,7 @@ static int kvm_get_vpa(CPUState *cs)
|
||||
static int kvm_put_vpa(CPUState *cs)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
struct kvm_one_reg reg;
|
||||
int ret;
|
||||
|
||||
@ -1593,70 +1597,93 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
|
||||
}
|
||||
}
|
||||
|
||||
static int kvm_handle_hw_breakpoint(CPUState *cs,
|
||||
struct kvm_debug_exit_arch *arch_info)
|
||||
{
|
||||
int handle = 0;
|
||||
int n;
|
||||
int flag = 0;
|
||||
|
||||
if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
|
||||
if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
|
||||
n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
|
||||
if (n >= 0) {
|
||||
handle = 1;
|
||||
}
|
||||
} else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
|
||||
KVMPPC_DEBUG_WATCH_WRITE)) {
|
||||
n = find_hw_watchpoint(arch_info->address, &flag);
|
||||
if (n >= 0) {
|
||||
handle = 1;
|
||||
cs->watchpoint_hit = &hw_watchpoint;
|
||||
hw_watchpoint.vaddr = hw_debug_points[n].addr;
|
||||
hw_watchpoint.flags = flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
static int kvm_handle_singlestep(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kvm_handle_sw_breakpoint(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
|
||||
int handle = 0;
|
||||
int n;
|
||||
int flag = 0;
|
||||
|
||||
if (cs->singlestep_enabled) {
|
||||
handle = 1;
|
||||
} else if (arch_info->status) {
|
||||
if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
|
||||
if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
|
||||
n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
|
||||
if (n >= 0) {
|
||||
handle = 1;
|
||||
}
|
||||
} else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
|
||||
KVMPPC_DEBUG_WATCH_WRITE)) {
|
||||
n = find_hw_watchpoint(arch_info->address, &flag);
|
||||
if (n >= 0) {
|
||||
handle = 1;
|
||||
cs->watchpoint_hit = &hw_watchpoint;
|
||||
hw_watchpoint.vaddr = hw_debug_points[n].addr;
|
||||
hw_watchpoint.flags = flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
|
||||
handle = 1;
|
||||
} else {
|
||||
/* QEMU is not able to handle debug exception, so inject
|
||||
* program exception to guest;
|
||||
* Yes program exception NOT debug exception !!
|
||||
* When QEMU is using debug resources then debug exception must
|
||||
* be always set. To achieve this we set MSR_DE and also set
|
||||
* MSRP_DEP so guest cannot change MSR_DE.
|
||||
* When emulating debug resource for guest we want guest
|
||||
* to control MSR_DE (enable/disable debug interrupt on need).
|
||||
* Supporting both configurations are NOT possible.
|
||||
* So the result is that we cannot share debug resources
|
||||
* between QEMU and Guest on BOOKE architecture.
|
||||
* In the current design QEMU gets the priority over guest,
|
||||
* this means that if QEMU is using debug resources then guest
|
||||
* cannot use them;
|
||||
* For software breakpoint QEMU uses a privileged instruction;
|
||||
* So there cannot be any reason that we are here for guest
|
||||
* set debug exception, only possibility is guest executed a
|
||||
* privileged / illegal instruction and that's why we are
|
||||
* injecting a program interrupt.
|
||||
*/
|
||||
|
||||
cpu_synchronize_state(cs);
|
||||
/* env->nip is PC, so increment this by 4 to use
|
||||
* ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
|
||||
*/
|
||||
env->nip += 4;
|
||||
cs->exception_index = POWERPC_EXCP_PROGRAM;
|
||||
env->error_code = POWERPC_EXCP_INVAL;
|
||||
ppc_cpu_do_interrupt(cs);
|
||||
return kvm_handle_singlestep();
|
||||
}
|
||||
|
||||
return handle;
|
||||
if (arch_info->status) {
|
||||
return kvm_handle_hw_breakpoint(cs, arch_info);
|
||||
}
|
||||
|
||||
if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
|
||||
return kvm_handle_sw_breakpoint();
|
||||
}
|
||||
|
||||
/*
|
||||
* QEMU is not able to handle debug exception, so inject
|
||||
* program exception to guest;
|
||||
* Yes program exception NOT debug exception !!
|
||||
* When QEMU is using debug resources then debug exception must
|
||||
* be always set. To achieve this we set MSR_DE and also set
|
||||
* MSRP_DEP so guest cannot change MSR_DE.
|
||||
* When emulating debug resource for guest we want guest
|
||||
* to control MSR_DE (enable/disable debug interrupt on need).
|
||||
* Supporting both configurations are NOT possible.
|
||||
* So the result is that we cannot share debug resources
|
||||
* between QEMU and Guest on BOOKE architecture.
|
||||
* In the current design QEMU gets the priority over guest,
|
||||
* this means that if QEMU is using debug resources then guest
|
||||
* cannot use them;
|
||||
* For software breakpoint QEMU uses a privileged instruction;
|
||||
* So there cannot be any reason that we are here for guest
|
||||
* set debug exception, only possibility is guest executed a
|
||||
* privileged / illegal instruction and that's why we are
|
||||
* injecting a program interrupt.
|
||||
*/
|
||||
cpu_synchronize_state(cs);
|
||||
/*
|
||||
* env->nip is PC, so increment this by 4 to use
|
||||
* ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
|
||||
*/
|
||||
env->nip += 4;
|
||||
cs->exception_index = POWERPC_EXCP_PROGRAM;
|
||||
env->error_code = POWERPC_EXCP_INVAL;
|
||||
ppc_cpu_do_interrupt(cs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
@ -1927,6 +1954,16 @@ uint64_t kvmppc_get_clockfreq(void)
|
||||
return kvmppc_read_int_cpu_dt("clock-frequency");
|
||||
}
|
||||
|
||||
static int kvmppc_get_dec_bits(void)
|
||||
{
|
||||
int nr_bits = kvmppc_read_int_cpu_dt("ibm,dec-bits");
|
||||
|
||||
if (nr_bits > 0) {
|
||||
return nr_bits;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
|
||||
{
|
||||
PowerPCCPU *cpu = ppc_env_get_cpu(env);
|
||||
@ -2007,6 +2044,11 @@ void kvmppc_enable_clear_ref_mod_hcalls(void)
|
||||
kvmppc_enable_hcall(kvm_state, H_CLEAR_MOD);
|
||||
}
|
||||
|
||||
void kvmppc_enable_h_page_init(void)
|
||||
{
|
||||
kvmppc_enable_hcall(kvm_state, H_PAGE_INIT);
|
||||
}
|
||||
|
||||
void kvmppc_set_papr(PowerPCCPU *cpu)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
@ -2379,7 +2421,13 @@ static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
|
||||
|
||||
static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
|
||||
{
|
||||
if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
|
||||
if ((~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) &&
|
||||
(~c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) &&
|
||||
(~c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED)) {
|
||||
return SPAPR_CAP_FIXED_NA;
|
||||
} else if (c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) {
|
||||
return SPAPR_CAP_WORKAROUND;
|
||||
} else if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
|
||||
return SPAPR_CAP_FIXED_CCD;
|
||||
} else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
|
||||
return SPAPR_CAP_FIXED_IBS;
|
||||
@ -2388,6 +2436,14 @@ static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_cap_ppc_count_cache_flush_assist(struct kvm_ppc_cpu_char c)
|
||||
{
|
||||
if (c.character & c.character_mask & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kvmppc_get_cpu_characteristics(KVMState *s)
|
||||
{
|
||||
struct kvm_ppc_cpu_char c;
|
||||
@ -2410,6 +2466,8 @@ static void kvmppc_get_cpu_characteristics(KVMState *s)
|
||||
cap_ppc_safe_cache = parse_cap_ppc_safe_cache(c);
|
||||
cap_ppc_safe_bounds_check = parse_cap_ppc_safe_bounds_check(c);
|
||||
cap_ppc_safe_indirect_branch = parse_cap_ppc_safe_indirect_branch(c);
|
||||
cap_ppc_count_cache_flush_assist =
|
||||
parse_cap_ppc_count_cache_flush_assist(c);
|
||||
}
|
||||
|
||||
int kvmppc_get_cap_safe_cache(void)
|
||||
@ -2427,6 +2485,11 @@ int kvmppc_get_cap_safe_indirect_branch(void)
|
||||
return cap_ppc_safe_indirect_branch;
|
||||
}
|
||||
|
||||
int kvmppc_get_cap_count_cache_flush_assist(void)
|
||||
{
|
||||
return cap_ppc_count_cache_flush_assist;
|
||||
}
|
||||
|
||||
bool kvmppc_has_cap_nested_kvm_hv(void)
|
||||
{
|
||||
return !!cap_ppc_nested_kvm_hv;
|
||||
@ -2442,6 +2505,35 @@ bool kvmppc_has_cap_spapr_vfio(void)
|
||||
return cap_spapr_vfio;
|
||||
}
|
||||
|
||||
int kvmppc_get_cap_large_decr(void)
|
||||
{
|
||||
return cap_large_decr;
|
||||
}
|
||||
|
||||
int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
uint64_t lpcr;
|
||||
|
||||
kvm_get_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
|
||||
/* Do we need to modify the LPCR? */
|
||||
if (!!(lpcr & LPCR_LD) != !!enable) {
|
||||
if (enable) {
|
||||
lpcr |= LPCR_LD;
|
||||
} else {
|
||||
lpcr &= ~LPCR_LD;
|
||||
}
|
||||
kvm_set_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
|
||||
kvm_get_one_reg(cs, KVM_REG_PPC_LPCR_64, &lpcr);
|
||||
|
||||
if (!!(lpcr & LPCR_LD) != !!enable) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
|
||||
{
|
||||
uint32_t host_pvr = mfpvr();
|
||||
|
@ -23,6 +23,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
|
||||
void kvmppc_enable_logical_ci_hcalls(void);
|
||||
void kvmppc_enable_set_mode_hcall(void);
|
||||
void kvmppc_enable_clear_ref_mod_hcalls(void);
|
||||
void kvmppc_enable_h_page_init(void);
|
||||
void kvmppc_set_papr(PowerPCCPU *cpu);
|
||||
int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
|
||||
void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
|
||||
@ -62,8 +63,11 @@ bool kvmppc_has_cap_mmu_hash_v3(void);
|
||||
int kvmppc_get_cap_safe_cache(void);
|
||||
int kvmppc_get_cap_safe_bounds_check(void);
|
||||
int kvmppc_get_cap_safe_indirect_branch(void);
|
||||
int kvmppc_get_cap_count_cache_flush_assist(void);
|
||||
bool kvmppc_has_cap_nested_kvm_hv(void);
|
||||
int kvmppc_set_cap_nested_kvm_hv(int enable);
|
||||
int kvmppc_get_cap_large_decr(void);
|
||||
int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable);
|
||||
int kvmppc_enable_hwrng(void);
|
||||
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
|
||||
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
|
||||
@ -135,6 +139,10 @@ static inline void kvmppc_enable_clear_ref_mod_hcalls(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void kvmppc_enable_h_page_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void kvmppc_set_papr(PowerPCCPU *cpu)
|
||||
{
|
||||
}
|
||||
@ -322,6 +330,11 @@ static inline int kvmppc_get_cap_safe_indirect_branch(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kvmppc_get_cap_count_cache_flush_assist(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool kvmppc_has_cap_nested_kvm_hv(void)
|
||||
{
|
||||
return false;
|
||||
@ -332,6 +345,16 @@ static inline int kvmppc_set_cap_nested_kvm_hv(int enable)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int kvmppc_get_cap_large_decr(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int kvmppc_enable_hwrng(void)
|
||||
{
|
||||
return -1;
|
||||
|
@ -150,7 +150,7 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size,
|
||||
{
|
||||
ppc_vsr_t *v = pv;
|
||||
|
||||
v->u64[0] = qemu_get_be64(f);
|
||||
v->VsrD(0) = qemu_get_be64(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -160,7 +160,7 @@ static int put_fpr(QEMUFile *f, void *pv, size_t size,
|
||||
{
|
||||
ppc_vsr_t *v = pv;
|
||||
|
||||
qemu_put_be64(f, v->u64[0]);
|
||||
qemu_put_be64(f, v->VsrD(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ static int get_vsr(QEMUFile *f, void *pv, size_t size,
|
||||
{
|
||||
ppc_vsr_t *v = pv;
|
||||
|
||||
v->u64[1] = qemu_get_be64(f);
|
||||
v->VsrD(1) = qemu_get_be64(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -191,7 +191,7 @@ static int put_vsr(QEMUFile *f, void *pv, size_t size,
|
||||
{
|
||||
ppc_vsr_t *v = pv;
|
||||
|
||||
qemu_put_be64(f, v->u64[1]);
|
||||
qemu_put_be64(f, v->VsrD(1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1109,7 +1109,7 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val)
|
||||
case POWERPC_MMU_3_00: /* P9 */
|
||||
lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
|
||||
(LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
|
||||
LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR |
|
||||
LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
|
||||
(LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
|
||||
LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | LPCR_TC |
|
||||
LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE);
|
||||
|
@ -6677,34 +6677,22 @@ GEN_TM_PRIV_NOOP(trechkpt);
|
||||
|
||||
static inline void get_fpr(TCGv_i64 dst, int regno)
|
||||
{
|
||||
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
|
||||
tcg_gen_ld_i64(dst, cpu_env, fpr_offset(regno));
|
||||
}
|
||||
|
||||
static inline void set_fpr(int regno, TCGv_i64 src)
|
||||
{
|
||||
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[regno].u64[0]));
|
||||
tcg_gen_st_i64(src, cpu_env, fpr_offset(regno));
|
||||
}
|
||||
|
||||
static inline void get_avr64(TCGv_i64 dst, int regno, bool high)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
|
||||
vsr[32 + regno].u64[(high ? 0 : 1)]));
|
||||
#else
|
||||
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState,
|
||||
vsr[32 + regno].u64[(high ? 1 : 0)]));
|
||||
#endif
|
||||
tcg_gen_ld_i64(dst, cpu_env, avr64_offset(regno, high));
|
||||
}
|
||||
|
||||
static inline void set_avr64(int regno, TCGv_i64 src, bool high)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
|
||||
vsr[32 + regno].u64[(high ? 0 : 1)]));
|
||||
#else
|
||||
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState,
|
||||
vsr[32 + regno].u64[(high ? 1 : 0)]));
|
||||
#endif
|
||||
tcg_gen_st_i64(src, cpu_env, avr64_offset(regno, high));
|
||||
}
|
||||
|
||||
#include "translate/fp-impl.inc.c"
|
||||
@ -7417,7 +7405,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||
#if !defined(NO_TIMER_DUMP)
|
||||
cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
" DECR %08" PRIu32
|
||||
" DECR " TARGET_FMT_lu
|
||||
#endif
|
||||
"\n",
|
||||
cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
|
||||
|
@ -10,15 +10,10 @@
|
||||
static inline TCGv_ptr gen_avr_ptr(int reg)
|
||||
{
|
||||
TCGv_ptr r = tcg_temp_new_ptr();
|
||||
tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[32 + reg].u64[0]));
|
||||
tcg_gen_addi_ptr(r, cpu_env, avr_full_offset(reg));
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline long avr64_offset(int reg, bool high)
|
||||
{
|
||||
return offsetof(CPUPPCState, vsr[32 + reg].u64[(high ? 0 : 1)]);
|
||||
}
|
||||
|
||||
#define GEN_VR_LDX(name, opc2, opc3) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
@ -205,7 +200,7 @@ static void gen_mtvscr(DisasContext *ctx)
|
||||
}
|
||||
|
||||
val = tcg_temp_new_i32();
|
||||
bofs = avr64_offset(rB(ctx->opcode), true);
|
||||
bofs = avr_full_offset(rB(ctx->opcode));
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
bofs += 3 * 4;
|
||||
#endif
|
||||
@ -284,9 +279,9 @@ static void glue(gen_, name)(DisasContext *ctx) \
|
||||
} \
|
||||
\
|
||||
tcg_op(vece, \
|
||||
avr64_offset(rD(ctx->opcode), true), \
|
||||
avr64_offset(rA(ctx->opcode), true), \
|
||||
avr64_offset(rB(ctx->opcode), true), \
|
||||
avr_full_offset(rD(ctx->opcode)), \
|
||||
avr_full_offset(rA(ctx->opcode)), \
|
||||
avr_full_offset(rB(ctx->opcode)), \
|
||||
16, 16); \
|
||||
}
|
||||
|
||||
@ -578,10 +573,10 @@ static void glue(gen_, NAME)(DisasContext *ctx) \
|
||||
gen_exception(ctx, POWERPC_EXCP_VPU); \
|
||||
return; \
|
||||
} \
|
||||
tcg_gen_gvec_4(avr64_offset(rD(ctx->opcode), true), \
|
||||
tcg_gen_gvec_4(avr_full_offset(rD(ctx->opcode)), \
|
||||
offsetof(CPUPPCState, vscr_sat), \
|
||||
avr64_offset(rA(ctx->opcode), true), \
|
||||
avr64_offset(rB(ctx->opcode), true), \
|
||||
avr_full_offset(rA(ctx->opcode)), \
|
||||
avr_full_offset(rB(ctx->opcode)), \
|
||||
16, 16, &g); \
|
||||
}
|
||||
|
||||
@ -755,7 +750,7 @@ static void glue(gen_, name)(DisasContext *ctx) \
|
||||
return; \
|
||||
} \
|
||||
simm = SIMM5(ctx->opcode); \
|
||||
tcg_op(avr64_offset(rD(ctx->opcode), true), 16, 16, simm); \
|
||||
tcg_op(avr_full_offset(rD(ctx->opcode)), 16, 16, simm); \
|
||||
}
|
||||
|
||||
GEN_VXFORM_DUPI(vspltisb, tcg_gen_gvec_dup8i, 6, 12);
|
||||
@ -850,8 +845,8 @@ static void gen_vsplt(DisasContext *ctx, int vece)
|
||||
}
|
||||
|
||||
uimm = UIMM5(ctx->opcode);
|
||||
bofs = avr64_offset(rB(ctx->opcode), true);
|
||||
dofs = avr64_offset(rD(ctx->opcode), true);
|
||||
bofs = avr_full_offset(rB(ctx->opcode));
|
||||
dofs = avr_full_offset(rD(ctx->opcode));
|
||||
|
||||
/* Experimental testing shows that hardware masks the immediate. */
|
||||
bofs += (uimm << vece) & 15;
|
||||
|
@ -1,54 +1,23 @@
|
||||
/*** VSX extension ***/
|
||||
|
||||
static inline void get_vsr(TCGv_i64 dst, int n)
|
||||
{
|
||||
tcg_gen_ld_i64(dst, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
|
||||
}
|
||||
|
||||
static inline void set_vsr(int n, TCGv_i64 src)
|
||||
{
|
||||
tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1]));
|
||||
}
|
||||
|
||||
static inline int vsr_full_offset(int n)
|
||||
{
|
||||
return offsetof(CPUPPCState, vsr[n].u64[0]);
|
||||
}
|
||||
|
||||
static inline void get_cpu_vsrh(TCGv_i64 dst, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
get_fpr(dst, n);
|
||||
} else {
|
||||
get_avr64(dst, n - 32, true);
|
||||
}
|
||||
tcg_gen_ld_i64(dst, cpu_env, vsr64_offset(n, true));
|
||||
}
|
||||
|
||||
static inline void get_cpu_vsrl(TCGv_i64 dst, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
get_vsr(dst, n);
|
||||
} else {
|
||||
get_avr64(dst, n - 32, false);
|
||||
}
|
||||
tcg_gen_ld_i64(dst, cpu_env, vsr64_offset(n, false));
|
||||
}
|
||||
|
||||
static inline void set_cpu_vsrh(int n, TCGv_i64 src)
|
||||
{
|
||||
if (n < 32) {
|
||||
set_fpr(n, src);
|
||||
} else {
|
||||
set_avr64(n - 32, src, true);
|
||||
}
|
||||
tcg_gen_st_i64(src, cpu_env, vsr64_offset(n, true));
|
||||
}
|
||||
|
||||
static inline void set_cpu_vsrl(int n, TCGv_i64 src)
|
||||
{
|
||||
if (n < 32) {
|
||||
set_vsr(n, src);
|
||||
} else {
|
||||
set_avr64(n - 32, src, false);
|
||||
}
|
||||
tcg_gen_st_i64(src, cpu_env, vsr64_offset(n, false));
|
||||
}
|
||||
|
||||
#define VSX_LOAD_SCALAR(name, operation) \
|
||||
@ -1618,8 +1587,7 @@ static void gen_xsxsigdp(DisasContext *ctx)
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
|
||||
get_cpu_vsrh(t1, xB(ctx->opcode));
|
||||
tcg_gen_andi_i64(rt, t1, 0x000FFFFFFFFFFFFF);
|
||||
tcg_gen_or_i64(rt, rt, t0);
|
||||
tcg_gen_deposit_i64(rt, t0, t1, 0, 52);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(t1);
|
||||
@ -1655,8 +1623,7 @@ static void gen_xsxsigqp(DisasContext *ctx)
|
||||
tcg_gen_movi_i64(t0, 0x0001000000000000);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
|
||||
tcg_gen_andi_i64(xth, xbh, 0x0000FFFFFFFFFFFF);
|
||||
tcg_gen_or_i64(xth, xth, t0);
|
||||
tcg_gen_deposit_i64(xth, t0, xbh, 0, 48);
|
||||
set_cpu_vsrh(rD(ctx->opcode) + 32, xth);
|
||||
tcg_gen_mov_i64(xtl, xbl);
|
||||
set_cpu_vsrl(rD(ctx->opcode) + 32, xtl);
|
||||
@ -1726,7 +1693,6 @@ static void gen_xviexpdp(DisasContext *ctx)
|
||||
TCGv_i64 xal;
|
||||
TCGv_i64 xbh;
|
||||
TCGv_i64 xbl;
|
||||
TCGv_i64 t0;
|
||||
|
||||
if (unlikely(!ctx->vsx_enabled)) {
|
||||
gen_exception(ctx, POWERPC_EXCP_VSXU);
|
||||
@ -1742,20 +1708,13 @@ static void gen_xviexpdp(DisasContext *ctx)
|
||||
get_cpu_vsrl(xal, xA(ctx->opcode));
|
||||
get_cpu_vsrh(xbh, xB(ctx->opcode));
|
||||
get_cpu_vsrl(xbl, xB(ctx->opcode));
|
||||
t0 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_andi_i64(xth, xah, 0x800FFFFFFFFFFFFF);
|
||||
tcg_gen_andi_i64(t0, xbh, 0x7FF);
|
||||
tcg_gen_shli_i64(t0, t0, 52);
|
||||
tcg_gen_or_i64(xth, xth, t0);
|
||||
tcg_gen_deposit_i64(xth, xah, xbh, 52, 11);
|
||||
set_cpu_vsrh(xT(ctx->opcode), xth);
|
||||
tcg_gen_andi_i64(xtl, xal, 0x800FFFFFFFFFFFFF);
|
||||
tcg_gen_andi_i64(t0, xbl, 0x7FF);
|
||||
tcg_gen_shli_i64(t0, t0, 52);
|
||||
tcg_gen_or_i64(xtl, xtl, t0);
|
||||
|
||||
tcg_gen_deposit_i64(xtl, xal, xbl, 52, 11);
|
||||
set_cpu_vsrl(xT(ctx->opcode), xtl);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free_i64(xth);
|
||||
tcg_temp_free_i64(xtl);
|
||||
tcg_temp_free_i64(xah);
|
||||
@ -1853,16 +1812,14 @@ static void gen_xvxsigdp(DisasContext *ctx)
|
||||
tcg_gen_movi_i64(t0, 0x0010000000000000);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
|
||||
tcg_gen_andi_i64(xth, xbh, 0x000FFFFFFFFFFFFF);
|
||||
tcg_gen_or_i64(xth, xth, t0);
|
||||
tcg_gen_deposit_i64(xth, t0, xbh, 0, 52);
|
||||
set_cpu_vsrh(xT(ctx->opcode), xth);
|
||||
|
||||
tcg_gen_extract_i64(exp, xbl, 52, 11);
|
||||
tcg_gen_movi_i64(t0, 0x0010000000000000);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, zr, zr, t0);
|
||||
tcg_gen_movcond_i64(TCG_COND_EQ, t0, exp, nan, zr, t0);
|
||||
tcg_gen_andi_i64(xtl, xbl, 0x000FFFFFFFFFFFFF);
|
||||
tcg_gen_or_i64(xtl, xtl, t0);
|
||||
tcg_gen_deposit_i64(xth, t0, xbl, 0, 52);
|
||||
set_cpu_vsrl(xT(ctx->opcode), xtl);
|
||||
|
||||
tcg_temp_free_i64(t0);
|
||||
|
@ -8376,6 +8376,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
|
||||
pcc->hash64_opts = &ppc_hash64_opts_basic;
|
||||
pcc->lrg_decr_bits = 32;
|
||||
#endif
|
||||
pcc->excp_model = POWERPC_EXCP_970;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_970;
|
||||
@ -8550,6 +8551,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
|
||||
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
|
||||
pcc->lrg_decr_bits = 32;
|
||||
#endif
|
||||
pcc->excp_model = POWERPC_EXCP_POWER7;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
|
||||
@ -8718,6 +8720,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
|
||||
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
|
||||
pcc->lrg_decr_bits = 32;
|
||||
#endif
|
||||
pcc->excp_model = POWERPC_EXCP_POWER8;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
|
||||
@ -8892,7 +8895,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
|
||||
PPC_MEM_SYNC | PPC_MEM_EIEIO |
|
||||
PPC_MEM_TLBSYNC |
|
||||
PPC_64B | PPC_64BX | PPC_ALTIVEC |
|
||||
PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
|
||||
PPC_SEGMENT_64B | PPC_SLBI |
|
||||
PPC_POPCNTB | PPC_POPCNTWD |
|
||||
PPC_CILDST;
|
||||
@ -8904,6 +8907,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||
PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
|
||||
PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
|
||||
pcc->msr_mask = (1ull << MSR_SF) |
|
||||
(1ull << MSR_SHV) |
|
||||
(1ull << MSR_TM) |
|
||||
(1ull << MSR_VR) |
|
||||
(1ull << MSR_VSX) |
|
||||
@ -8926,6 +8930,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||
/* segment page size remain the same */
|
||||
pcc->hash64_opts = &ppc_hash64_opts_POWER7;
|
||||
pcc->radix_page_info = &POWER9_radix_page_info;
|
||||
pcc->lrg_decr_bits = 56;
|
||||
#endif
|
||||
pcc->excp_model = POWERPC_EXCP_POWER9;
|
||||
pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
|
||||
|
@ -100,7 +100,9 @@ static testdef_t tests[] = {
|
||||
{ "ppc64", "ppce500", "", "U-Boot" },
|
||||
{ "ppc64", "40p", "-m 192", "Memory: 192M" },
|
||||
{ "ppc64", "mac99", "", "PowerPC,970FX" },
|
||||
{ "ppc64", "pseries", "", "Open Firmware" },
|
||||
{ "ppc64", "pseries",
|
||||
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken",
|
||||
"Open Firmware" },
|
||||
{ "ppc64", "powernv", "-cpu POWER8", "OPAL" },
|
||||
{ "ppc64", "sam460ex", "-device e1000", "8086 100e" },
|
||||
{ "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
|
||||
|
@ -39,7 +39,6 @@ static const PnvChip pnv_chips[] = {
|
||||
.cfam_id = 0x120d304980000000ull,
|
||||
.first_core = 0x1,
|
||||
},
|
||||
#if 0 /* POWER9 support is not ready yet */
|
||||
{
|
||||
.chip_type = PNV_CHIP_POWER9,
|
||||
.cpu_model = "POWER9",
|
||||
@ -47,7 +46,6 @@ static const PnvChip pnv_chips[] = {
|
||||
.cfam_id = 0x220d104900008000ull,
|
||||
.first_core = 0x0,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
|
||||
|
@ -44,11 +44,18 @@ static void check_guest_memory(QTestState *qts)
|
||||
|
||||
static void test_machine(const void *machine)
|
||||
{
|
||||
const char *extra_args;
|
||||
const char *extra_args = "";
|
||||
QTestState *qts;
|
||||
|
||||
/* The pseries firmware boots much faster without the default devices */
|
||||
extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : "";
|
||||
/*
|
||||
* The pseries firmware boots much faster without the default
|
||||
* devices, it also needs Spectre/Meltdown workarounds disabled to
|
||||
* avoid warnings with TCG
|
||||
*/
|
||||
if (strcmp(machine, "pseries") == 0) {
|
||||
extra_args = "-nodefaults"
|
||||
" -machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken";
|
||||
}
|
||||
|
||||
qts = qtest_initf("-M %s,accel=tcg %s -prom-env 'use-nvramrc?=true' "
|
||||
"-prom-env 'nvramrc=%x %x l!' ", (const char *)machine,
|
||||
|
@ -25,6 +25,7 @@ static char disk[] = "tests/pxe-test-disk-XXXXXX";
|
||||
typedef struct testdef {
|
||||
const char *machine; /* Machine type */
|
||||
const char *model; /* NIC device model */
|
||||
const char *extra; /* Any additional parameters */
|
||||
} testdef_t;
|
||||
|
||||
static testdef_t x86_tests[] = {
|
||||
@ -44,13 +45,16 @@ static testdef_t x86_tests_slow[] = {
|
||||
};
|
||||
|
||||
static testdef_t ppc64_tests[] = {
|
||||
{ "pseries", "spapr-vlan" },
|
||||
{ "pseries", "virtio-net-pci", },
|
||||
{ "pseries", "spapr-vlan",
|
||||
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
|
||||
{ "pseries", "virtio-net-pci",
|
||||
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static testdef_t ppc64_tests_slow[] = {
|
||||
{ "pseries", "e1000" },
|
||||
{ "pseries", "e1000",
|
||||
"-machine cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@ -63,13 +67,18 @@ static void test_pxe_one(const testdef_t *test, bool ipv6)
|
||||
{
|
||||
QTestState *qts;
|
||||
char *args;
|
||||
const char *extra = test->extra;
|
||||
|
||||
if (!extra) {
|
||||
extra = "";
|
||||
}
|
||||
|
||||
args = g_strdup_printf(
|
||||
"-machine %s,accel=kvm:tcg -nodefaults -boot order=n "
|
||||
"-netdev user,id=" NETNAME ",tftp=./,bootfile=%s,ipv4=%s,ipv6=%s "
|
||||
"-device %s,bootindex=1,netdev=" NETNAME,
|
||||
"-device %s,bootindex=1,netdev=" NETNAME " %s",
|
||||
test->machine, disk, ipv6 ? "off" : "on", ipv6 ? "on" : "off",
|
||||
test->model);
|
||||
test->model, extra);
|
||||
|
||||
qts = qtest_init(args);
|
||||
boot_sector_test(qts);
|
||||
|
Loading…
Reference in New Issue
Block a user