mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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
|
||||
|
||||
+29
-29
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
+43
-43
@@ -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 */
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+12
-12
@@ -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[] = {
|
||||
|
||||
+103
-10
@@ -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);
|
||||
|
||||
+55
-55
@@ -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,
|
||||
|
||||
+21
-21
@@ -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")) {
|
||||
|
||||
+209
-43
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+175
-14
@@ -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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user