ppc patch queue for 2022-04-20

First batch of ppc patches for QEMU 7.1:
 
 - skiboot firmware version bump
 - pseries: add 2M DDW pagesize
 - pseries: make virtual hypervisor code TCG only
 - powernv: introduce GPIO lines for PSIHB device
 - powernv: remove PCIE root bridge LSI
 - target/ppc: alternative softfloat 128 bit integer support
 - assorted fixes
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCYmB/ngAKCRA82cqW3gMx
 ZE10AP4wPeJQ3fxXb5ylVtL4qkJaLWy6VrJBQSKSb5YEA0fhegEA9ZufpnENQePU
 gZF0eFAQK/DbSnDyvRQVpGcJM0K1UgI=
 =nVRw
 -----END PGP SIGNATURE-----

Merge tag 'pull-ppc-20220420-2' of https://gitlab.com/danielhb/qemu into staging

ppc patch queue for 2022-04-20

First batch of ppc patches for QEMU 7.1:

- skiboot firmware version bump
- pseries: add 2M DDW pagesize
- pseries: make virtual hypervisor code TCG only
- powernv: introduce GPIO lines for PSIHB device
- powernv: remove PCIE root bridge LSI
- target/ppc: alternative softfloat 128 bit integer support
- assorted fixes

# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCYmB/ngAKCRA82cqW3gMx
# ZE10AP4wPeJQ3fxXb5ylVtL4qkJaLWy6VrJBQSKSb5YEA0fhegEA9ZufpnENQePU
# gZF0eFAQK/DbSnDyvRQVpGcJM0K1UgI=
# =nVRw
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 20 Apr 2022 02:48:14 PM PDT
# gpg:                using EDDSA key 17EBFF9923D01800AF2838193CD9CA96DE033164
# gpg: Can't check signature: No public key

* tag 'pull-ppc-20220420-2' of https://gitlab.com/danielhb/qemu: (23 commits)
  hw/ppc: change indentation to spaces from TABs
  target/ppc: Add two missing register callbacks on POWER10
  ppc/pnv: Remove LSI on the PCIE host bridge
  pcie: Don't try triggering a LSI when not defined
  ppc/vof: Fix uninitialized string tracing
  hw/ppc/ppc405_boards: Initialize g_autofree pointer
  target/ppc: implement xscvqp[su]qz
  target/ppc: implement xscv[su]qqp
  softfloat: add float128_to_int128
  softfloat: add float128_to_uint128
  softfloat: add int128_to_float128
  softfloat: add uint128_to_float128
  qemu/int128: add int128_urshift
  target/ppc: Improve KVM hypercall trace
  spapr: Move nested KVM hypercalls under a TCG only config.
  spapr: Move hypercall_register_softmmu
  ppc/pnv: Remove useless checks in set_irq handlers
  ppc/pnv: Remove PnvPsiClas::irq_set
  ppc/pnv: Remove PnvOCC::psi link
  ppc/pnv: Remove PnvLpcController::psi link
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2022-04-20 21:54:24 -07:00
commit b1efff6bf0
32 changed files with 446 additions and 137 deletions

View File

@ -3154,6 +3154,60 @@ static int64_t float128_to_int64_scalbn(float128 a, FloatRoundMode rmode,
return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
}
static Int128 float128_to_int128_scalbn(float128 a, FloatRoundMode rmode,
int scale, float_status *s)
{
int flags = 0;
Int128 r;
FloatParts128 p;
float128_unpack_canonical(&p, a, s);
switch (p.cls) {
case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan:
flags |= float_flag_invalid;
r = UINT128_MAX;
break;
case float_class_inf:
flags = float_flag_invalid | float_flag_invalid_cvti;
r = p.sign ? INT128_MIN : INT128_MAX;
break;
case float_class_zero:
return int128_zero();
case float_class_normal:
if (parts_round_to_int_normal(&p, rmode, scale, 128 - 2)) {
flags = float_flag_inexact;
}
if (p.exp < 127) {
int shift = 127 - p.exp;
r = int128_urshift(int128_make128(p.frac_lo, p.frac_hi), shift);
if (p.sign) {
r = int128_neg(r);
}
} else if (p.exp == 127 && p.sign && p.frac_lo == 0 &&
p.frac_hi == DECOMPOSED_IMPLICIT_BIT) {
r = INT128_MIN;
} else {
flags = float_flag_invalid | float_flag_invalid_cvti;
r = p.sign ? INT128_MIN : INT128_MAX;
}
break;
default:
g_assert_not_reached();
}
float_raise(flags, s);
return r;
}
static int32_t floatx80_to_int32_scalbn(floatx80 a, FloatRoundMode rmode,
int scale, float_status *s)
{
@ -3236,6 +3290,11 @@ int64_t float128_to_int64(float128 a, float_status *s)
return float128_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
}
Int128 float128_to_int128(float128 a, float_status *s)
{
return float128_to_int128_scalbn(a, s->float_rounding_mode, 0, s);
}
int32_t floatx80_to_int32(floatx80 a, float_status *s)
{
return floatx80_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
@ -3301,6 +3360,11 @@ int64_t float128_to_int64_round_to_zero(float128 a, float_status *s)
return float128_to_int64_scalbn(a, float_round_to_zero, 0, s);
}
Int128 float128_to_int128_round_to_zero(float128 a, float_status *s)
{
return float128_to_int128_scalbn(a, float_round_to_zero, 0, s);
}
int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *s)
{
return floatx80_to_int32_scalbn(a, float_round_to_zero, 0, s);
@ -3480,6 +3544,61 @@ static uint64_t float128_to_uint64_scalbn(float128 a, FloatRoundMode rmode,
return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
}
static Int128 float128_to_uint128_scalbn(float128 a, FloatRoundMode rmode,
int scale, float_status *s)
{
int flags = 0;
Int128 r;
FloatParts128 p;
float128_unpack_canonical(&p, a, s);
switch (p.cls) {
case float_class_snan:
flags |= float_flag_invalid_snan;
/* fall through */
case float_class_qnan:
flags |= float_flag_invalid;
r = UINT128_MAX;
break;
case float_class_inf:
flags = float_flag_invalid | float_flag_invalid_cvti;
r = p.sign ? int128_zero() : UINT128_MAX;
break;
case float_class_zero:
return int128_zero();
case float_class_normal:
if (parts_round_to_int_normal(&p, rmode, scale, 128 - 2)) {
flags = float_flag_inexact;
if (p.cls == float_class_zero) {
r = int128_zero();
break;
}
}
if (p.sign) {
flags = float_flag_invalid | float_flag_invalid_cvti;
r = int128_zero();
} else if (p.exp <= 127) {
int shift = 127 - p.exp;
r = int128_urshift(int128_make128(p.frac_lo, p.frac_hi), shift);
} else {
flags = float_flag_invalid | float_flag_invalid_cvti;
r = UINT128_MAX;
}
break;
default:
g_assert_not_reached();
}
float_raise(flags, s);
return r;
}
uint8_t float16_to_uint8(float16 a, float_status *s)
{
return float16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
@ -3540,6 +3659,11 @@ uint64_t float128_to_uint64(float128 a, float_status *s)
return float128_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
}
Int128 float128_to_uint128(float128 a, float_status *s)
{
return float128_to_uint128_scalbn(a, s->float_rounding_mode, 0, s);
}
uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s)
{
return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
@ -3595,6 +3719,11 @@ uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *s)
return float128_to_uint64_scalbn(a, float_round_to_zero, 0, s);
}
Int128 float128_to_uint128_round_to_zero(float128 a, float_status *s)
{
return float128_to_uint128_scalbn(a, float_round_to_zero, 0, s);
}
uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
{
return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
@ -3780,6 +3909,35 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status *status)
return int64_to_bfloat16_scalbn(a, 0, status);
}
float128 int128_to_float128(Int128 a, float_status *status)
{
FloatParts128 p = { };
int shift;
if (int128_nz(a)) {
p.cls = float_class_normal;
if (!int128_nonneg(a)) {
p.sign = true;
a = int128_neg(a);
}
shift = clz64(int128_gethi(a));
if (shift == 64) {
shift += clz64(int128_getlo(a));
}
p.exp = 127 - shift;
a = int128_lshift(a, shift);
p.frac_hi = int128_gethi(a);
p.frac_lo = int128_getlo(a);
} else {
p.cls = float_class_zero;
}
return float128_round_pack_canonical(&p, status);
}
float128 int64_to_float128(int64_t a, float_status *status)
{
FloatParts128 p;
@ -3969,6 +4127,31 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
return float128_round_pack_canonical(&p, status);
}
float128 uint128_to_float128(Int128 a, float_status *status)
{
FloatParts128 p = { };
int shift;
if (int128_nz(a)) {
p.cls = float_class_normal;
shift = clz64(int128_gethi(a));
if (shift == 64) {
shift += clz64(int128_getlo(a));
}
p.exp = 127 - shift;
a = int128_lshift(a, shift);
p.frac_hi = int128_gethi(a);
p.frac_lo = int128_getlo(a);
} else {
p.cls = float_class_zero;
}
return float128_round_pack_canonical(&p, status);
}
/*
* Minimum and maximum
*/

View File

@ -1161,6 +1161,7 @@ static void pnv_phb3_root_port_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
pci_config_set_interrupt_pin(pci->config, 0);
}
static void pnv_phb3_root_port_class_init(ObjectClass *klass, void *data)

View File

@ -1771,6 +1771,7 @@ static void pnv_phb4_root_port_reset(DeviceState *dev)
pci_set_word(conf + PCI_PREF_MEMORY_LIMIT, 0xfff1);
pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */
pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0xffffffff);
pci_config_set_interrupt_pin(conf, 0);
}
static void pnv_phb4_root_port_realize(DeviceState *dev, Error **errp)

View File

@ -353,7 +353,7 @@ static void hotplug_event_notify(PCIDevice *dev)
msix_notify(dev, pcie_cap_flags_get_vector(dev));
} else if (msi_enabled(dev)) {
msi_notify(dev, pcie_cap_flags_get_vector(dev));
} else {
} else if (pci_intx(dev) != -1) {
pci_set_irq(dev, dev->exp.hpev_notified);
}
}
@ -361,7 +361,8 @@ static void hotplug_event_notify(PCIDevice *dev)
static void hotplug_event_clear(PCIDevice *dev)
{
hotplug_event_update_event_status(dev);
if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
if (!msix_enabled(dev) && !msi_enabled(dev) && pci_intx(dev) != -1 &&
!dev->exp.hpev_notified) {
pci_irq_deassert(dev);
}
}

View File

@ -290,7 +290,7 @@ static void pcie_aer_root_notify(PCIDevice *dev)
msix_notify(dev, pcie_aer_root_get_vector(dev));
} else if (msi_enabled(dev)) {
msi_notify(dev, pcie_aer_root_get_vector(dev));
} else {
} else if (pci_intx(dev) != -1) {
pci_irq_assert(dev);
}
}

View File

@ -614,24 +614,36 @@ static void pnv_reset(MachineState *machine)
static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
{
Pnv8Chip *chip8 = PNV8_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_EXTERNAL);
qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
return pnv_lpc_isa_create(&chip8->lpc, true, errp);
}
static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
{
Pnv8Chip *chip8 = PNV8_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_LPC_I2C);
qdev_connect_gpio_out(DEVICE(&chip8->lpc), 0, irq);
return pnv_lpc_isa_create(&chip8->lpc, false, errp);
}
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
{
Pnv9Chip *chip9 = PNV9_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip9->psi), PSIHB9_IRQ_LPCHC);
qdev_connect_gpio_out(DEVICE(&chip9->lpc), 0, irq);
return pnv_lpc_isa_create(&chip9->lpc, false, errp);
}
static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
{
Pnv10Chip *chip10 = PNV10_CHIP(chip);
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip10->psi), PSIHB9_IRQ_LPCHC);
qdev_connect_gpio_out(DEVICE(&chip10->lpc), 0, irq);
return pnv_lpc_isa_create(&chip10->lpc, false, errp);
}
@ -1222,8 +1234,6 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
&PNV_PSI(psi8)->xscom_regs);
/* Create LPC controller */
object_property_set_link(OBJECT(&chip8->lpc), "psi", OBJECT(&chip8->psi),
&error_abort);
qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);
@ -1243,12 +1253,12 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
}
/* Create the simplified OCC model */
object_property_set_link(OBJECT(&chip8->occ), "psi", OBJECT(&chip8->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip8->occ), NULL, errp)) {
return;
}
pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs);
qdev_connect_gpio_out(DEVICE(&chip8->occ), 0,
qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_OCC));
/* OCC SRAM model */
memory_region_add_subregion(get_system_memory(), PNV_OCC_SENSOR_BASE(chip),
@ -1507,8 +1517,6 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
&PNV_PSI(psi9)->xscom_regs);
/* LPC */
object_property_set_link(OBJECT(&chip9->lpc), "psi", OBJECT(&chip9->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip9->lpc), NULL, errp)) {
return;
}
@ -1520,12 +1528,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
(uint64_t) PNV9_LPCM_BASE(chip));
/* Create the simplified OCC model */
object_property_set_link(OBJECT(&chip9->occ), "psi", OBJECT(&chip9->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip9->occ), NULL, errp)) {
return;
}
pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs);
qdev_connect_gpio_out(DEVICE(&chip9->occ), 0, qdev_get_gpio_in(
DEVICE(&chip9->psi), PSIHB9_IRQ_OCC));
/* OCC SRAM model */
memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip),
@ -1712,8 +1720,6 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
&PNV_PSI(&chip10->psi)->xscom_regs);
/* LPC */
object_property_set_link(OBJECT(&chip10->lpc), "psi",
OBJECT(&chip10->psi), &error_abort);
if (!qdev_realize(DEVICE(&chip10->lpc), NULL, errp)) {
return;
}
@ -1725,13 +1731,13 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
(uint64_t) PNV10_LPCM_BASE(chip));
/* Create the simplified OCC model */
object_property_set_link(OBJECT(&chip10->occ), "psi", OBJECT(&chip10->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip10->occ), NULL, errp)) {
return;
}
pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
&chip10->occ.xscom_regs);
qdev_connect_gpio_out(DEVICE(&chip10->occ), 0, qdev_get_gpio_in(
DEVICE(&chip10->psi), PSIHB9_IRQ_OCC));
/* OCC SRAM model */
memory_region_add_subregion(get_system_memory(),

View File

@ -422,7 +422,6 @@ static const MemoryRegionOps pnv_lpc_mmio_ops = {
static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
{
bool lpc_to_opb_irq = false;
PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
/* Update LPC controller to OPB line */
if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) {
@ -445,7 +444,7 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
/* Reflect the interrupt */
pnv_psi_irq_set(lpc->psi, plc->psi_irq, lpc->opb_irq_stat != 0);
qemu_set_irq(lpc->psi_irq, lpc->opb_irq_stat != 0);
}
static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size)
@ -637,8 +636,6 @@ static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data)
xdc->dt_xscom = pnv_lpc_dt_xscom;
plc->psi_irq = PSIHB_IRQ_LPC_I2C;
device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
&plc->parent_realize);
}
@ -677,8 +674,6 @@ static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data)
dc->desc = "PowerNV LPC Controller POWER9";
plc->psi_irq = PSIHB9_IRQ_LPCHC;
device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
&plc->parent_realize);
}
@ -706,8 +701,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{
PnvLpcController *lpc = PNV_LPC(dev);
assert(lpc->psi);
/* Reg inits */
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B;
@ -746,12 +739,9 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
"lpc-hc", LPC_HC_REGS_OPB_SIZE);
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs);
}
static Property pnv_lpc_properties[] = {
DEFINE_PROP_LINK("psi", PnvLpcController, psi, TYPE_PNV_PSI, PnvPsi *),
DEFINE_PROP_END_OF_LIST(),
};
qdev_init_gpio_out(DEVICE(dev), &lpc->psi_irq, 1);
}
static void pnv_lpc_class_init(ObjectClass *klass, void *data)
{
@ -759,7 +749,6 @@ static void pnv_lpc_class_init(ObjectClass *klass, void *data)
dc->realize = pnv_lpc_realize;
dc->desc = "PowerNV LPC Controller";
device_class_set_props(dc, pnv_lpc_properties);
dc->user_creatable = false;
}
@ -803,7 +792,7 @@ static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level)
}
if (pnv->cpld_irqstate != old_state) {
pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_EXTERNAL, pnv->cpld_irqstate != 0);
qemu_set_irq(lpc->psi_irq, pnv->cpld_irqstate != 0);
}
}

View File

@ -21,6 +21,7 @@
#include "qapi/error.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_xscom.h"
@ -51,13 +52,12 @@
static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
{
bool irq_state;
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
val &= 0xffff000000000000ull;
occ->occmisc = val;
irq_state = !!(val >> 63);
pnv_psi_irq_set(occ->psi, poc->psi_irq, irq_state);
qemu_set_irq(occ->psi_irq, irq_state);
}
static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr,
@ -168,7 +168,6 @@ static void pnv_occ_power8_class_init(ObjectClass *klass, void *data)
poc->xscom_size = PNV_XSCOM_OCC_SIZE;
poc->xscom_ops = &pnv_occ_power8_xscom_ops;
poc->psi_irq = PSIHB_IRQ_OCC;
}
static const TypeInfo pnv_occ_power8_type_info = {
@ -241,7 +240,6 @@ static void pnv_occ_power9_class_init(ObjectClass *klass, void *data)
dc->desc = "PowerNV OCC Controller (POWER9)";
poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
poc->xscom_ops = &pnv_occ_power9_xscom_ops;
poc->psi_irq = PSIHB9_IRQ_OCC;
}
static const TypeInfo pnv_occ_power9_type_info = {
@ -269,8 +267,6 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
PnvOCC *occ = PNV_OCC(dev);
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
assert(occ->psi);
occ->occmisc = 0;
/* XScom region for OCC registers */
@ -281,12 +277,9 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&occ->sram_regs, OBJECT(dev), &pnv_occ_sram_ops,
occ, "occ-common-area",
PNV_OCC_SENSOR_DATA_BLOCK_SIZE);
}
static Property pnv_occ_properties[] = {
DEFINE_PROP_LINK("psi", PnvOCC, psi, TYPE_PNV_PSI, PnvPsi *),
DEFINE_PROP_END_OF_LIST(),
};
qdev_init_gpio_out(DEVICE(dev), &occ->psi_irq, 1);
}
static void pnv_occ_class_init(ObjectClass *klass, void *data)
{
@ -294,7 +287,6 @@ static void pnv_occ_class_init(ObjectClass *klass, void *data)
dc->realize = pnv_occ_realize;
dc->desc = "PowerNV OCC Controller";
device_class_set_props(dc, pnv_occ_properties);
dc->user_creatable = false;
}

View File

@ -184,8 +184,7 @@ static void pnv_psi_set_irsn(PnvPsi *psi, uint64_t val)
/*
* FSP and PSI interrupts are muxed under the same number.
*/
static const uint32_t xivr_regs[] = {
[PSIHB_IRQ_PSI] = PSIHB_XSCOM_XIVR_FSP,
static const uint32_t xivr_regs[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_FSP] = PSIHB_XSCOM_XIVR_FSP,
[PSIHB_IRQ_OCC] = PSIHB_XSCOM_XIVR_OCC,
[PSIHB_IRQ_FSI] = PSIHB_XSCOM_XIVR_FSI,
@ -194,8 +193,7 @@ static const uint32_t xivr_regs[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_XSCOM_XIVR_EXT,
};
static const uint32_t stat_regs[] = {
[PSIHB_IRQ_PSI] = PSIHB_XSCOM_CR,
static const uint32_t stat_regs[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_FSP] = PSIHB_XSCOM_CR,
[PSIHB_IRQ_OCC] = PSIHB_XSCOM_IRQ_STAT,
[PSIHB_IRQ_FSI] = PSIHB_XSCOM_IRQ_STAT,
@ -204,8 +202,7 @@ static const uint32_t stat_regs[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_XSCOM_IRQ_STAT,
};
static const uint64_t stat_bits[] = {
[PSIHB_IRQ_PSI] = PSIHB_CR_PSI_IRQ,
static const uint64_t stat_bits[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_FSP] = PSIHB_CR_FSP_IRQ,
[PSIHB_IRQ_OCC] = PSIHB_IRQ_STAT_OCC,
[PSIHB_IRQ_FSI] = PSIHB_IRQ_STAT_FSI,
@ -214,23 +211,14 @@ static const uint64_t stat_bits[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_IRQ_STAT_EXT,
};
void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state)
{
PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
}
static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
static void pnv_psi_power8_set_irq(void *opaque, int irq, int state)
{
PnvPsi *psi = opaque;
uint32_t xivr_reg;
uint32_t stat_reg;
uint32_t src;
bool masked;
if (irq > PSIHB_IRQ_EXTERNAL) {
qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
return;
}
xivr_reg = xivr_regs[irq];
stat_reg = stat_regs[irq];
@ -515,6 +503,8 @@ static void pnv_psi_power8_realize(DeviceState *dev, Error **errp)
ics_set_irq_type(ics, i, true);
}
qdev_init_gpio_in(dev, pnv_psi_power8_set_irq, ics->nr_irqs);
psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
/* XSCOM region for PSI registers */
@ -576,7 +566,6 @@ static void pnv_psi_power8_class_init(ObjectClass *klass, void *data)
ppc->xscom_pcba = PNV_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
ppc->bar_mask = PSIHB_BAR_MASK;
ppc->irq_set = pnv_psi_power8_irq_set;
ppc->compat = compat;
ppc->compat_size = sizeof(compat);
}
@ -814,15 +803,11 @@ static const MemoryRegionOps pnv_psi_p9_xscom_ops = {
}
};
static void pnv_psi_power9_irq_set(PnvPsi *psi, int irq, bool state)
static void pnv_psi_power9_set_irq(void *opaque, int irq, int state)
{
PnvPsi *psi = opaque;
uint64_t irq_method = psi->regs[PSIHB_REG(PSIHB9_INTERRUPT_CONTROL)];
if (irq > PSIHB9_NUM_IRQS) {
qemu_log_mask(LOG_GUEST_ERROR, "PSI: Unsupported irq %d\n", irq);
return;
}
if (irq_method & PSIHB9_IRQ_METHOD) {
qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
return;
@ -876,6 +861,8 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
psi->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc, xsrc->nr_irqs);
qdev_init_gpio_in(dev, pnv_psi_power9_set_irq, xsrc->nr_irqs);
/* XSCOM region for PSI registers */
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE);
@ -901,7 +888,6 @@ static void pnv_psi_power9_class_init(ObjectClass *klass, void *data)
ppc->xscom_pcba = PNV9_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
ppc->bar_mask = PSIHB9_BAR_MASK;
ppc->irq_set = pnv_psi_power9_irq_set;
ppc->compat = compat;
ppc->compat_size = sizeof(compat);

View File

@ -261,13 +261,13 @@ static void ref405ep_init(MachineState *machine)
/* allocate and load BIOS */
if (machine->firmware) {
MemoryRegion *bios = g_new(MemoryRegion, 1);
g_autofree char *filename;
g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
machine->firmware);
long bios_size;
memory_region_init_rom(bios, NULL, "ef405ep.bios", BIOS_SIZE,
&error_fatal);
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
if (!filename) {
error_report("Could not find firmware '%s'", machine->firmware);
exit(1);

View File

@ -3,9 +3,9 @@
*
* Copyright 2007 IBM Corporation.
* Authors:
* Jerone Young <jyoung5@us.ibm.com>
* Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* Hollis Blanchard <hollisb@us.ibm.com>
* Jerone Young <jyoung5@us.ibm.com>
* Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* Hollis Blanchard <hollisb@us.ibm.com>
*
* This work is licensed under the GNU GPL license version 2 or later.
*

View File

@ -1473,32 +1473,7 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
return H_FUNCTION;
}
#ifndef CONFIG_TCG
static target_ulong h_softmmu(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
g_assert_not_reached();
}
static void hypercall_register_softmmu(void)
{
/* hcall-pft */
spapr_register_hypercall(H_ENTER, h_softmmu);
spapr_register_hypercall(H_REMOVE, h_softmmu);
spapr_register_hypercall(H_PROTECT, h_softmmu);
spapr_register_hypercall(H_READ, h_softmmu);
/* hcall-bulk */
spapr_register_hypercall(H_BULK_REMOVE, h_softmmu);
}
#else
static void hypercall_register_softmmu(void)
{
/* DO NOTHING */
}
#endif
/* TCG only */
#ifdef CONFIG_TCG
#define PRTS_MASK 0x1f
static target_ulong h_set_ptbl(PowerPCCPU *cpu,
@ -1825,6 +1800,48 @@ out_restore_l1:
spapr_cpu->nested_host_state = NULL;
}
static void hypercall_register_nested(void)
{
spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
spapr_register_hypercall(KVMPPC_H_ENTER_NESTED, h_enter_nested);
spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
}
static void hypercall_register_softmmu(void)
{
/* DO NOTHING */
}
#else
void spapr_exit_nested(PowerPCCPU *cpu, int excp)
{
g_assert_not_reached();
}
static target_ulong h_softmmu(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
g_assert_not_reached();
}
static void hypercall_register_nested(void)
{
/* DO NOTHING */
}
static void hypercall_register_softmmu(void)
{
/* hcall-pft */
spapr_register_hypercall(H_ENTER, h_softmmu);
spapr_register_hypercall(H_REMOVE, h_softmmu);
spapr_register_hypercall(H_PROTECT, h_softmmu);
spapr_register_hypercall(H_READ, h_softmmu);
/* hcall-bulk */
spapr_register_hypercall(H_BULK_REMOVE, h_softmmu);
}
#endif
static void hypercall_register_types(void)
{
hypercall_register_softmmu();
@ -1881,10 +1898,7 @@ static void hypercall_register_types(void)
spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
spapr_register_hypercall(KVMPPC_H_ENTER_NESTED, h_enter_nested);
spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
hypercall_register_nested();
}
type_init(hypercall_register_types)

View File

@ -474,16 +474,16 @@ static void rtas_ibm_nmi_interlock(PowerPCCPU *cpu,
if (spapr->fwnmi_machine_check_interlock != cpu->vcpu_id) {
/*
* The vCPU that hit the NMI should invoke "ibm,nmi-interlock"
* The vCPU that hit the NMI should invoke "ibm,nmi-interlock"
* This should be PARAM_ERROR, but Linux calls "ibm,nmi-interlock"
* for system reset interrupts, despite them not being interlocked.
* PowerVM silently ignores this and returns success here. Returning
* failure causes Linux to print the error "FWNMI: nmi-interlock
* failed: -3", although no other apparent ill effects, this is a
* regression for the user when enabling FWNMI. So for now, match
* PowerVM. When most Linux clients are fixed, this could be
* changed.
*/
* for system reset interrupts, despite them not being interlocked.
* PowerVM silently ignores this and returns success here. Returning
* failure causes Linux to print the error "FWNMI: nmi-interlock
* failed: -3", although no other apparent ill effects, this is a
* regression for the user when enabling FWNMI. So for now, match
* PowerVM. When most Linux clients are fixed, this could be
* changed.
*/
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
return;
}

View File

@ -72,6 +72,7 @@ static uint32_t spapr_page_mask_to_query_mask(uint64_t page_mask)
const struct { int shift; uint32_t mask; } masks[] = {
{ 12, RTAS_DDW_PGSIZE_4K },
{ 16, RTAS_DDW_PGSIZE_64K },
{ 21, RTAS_DDW_PGSIZE_2M },
{ 24, RTAS_DDW_PGSIZE_16M },
{ 25, RTAS_DDW_PGSIZE_32M },
{ 26, RTAS_DDW_PGSIZE_64M },

View File

@ -293,7 +293,7 @@ static uint32_t vof_setprop(MachineState *ms, void *fdt, Vof *vof,
uint32_t nodeph, uint32_t pname,
uint32_t valaddr, uint32_t vallen)
{
char propname[OF_PROPNAME_LEN_MAX + 1];
char propname[OF_PROPNAME_LEN_MAX + 1] = "";
uint32_t ret = PROM_ERROR;
int offset, rc;
char trval[64] = "";

View File

@ -95,6 +95,7 @@ typedef enum {
#include "fpu/softfloat-types.h"
#include "fpu/softfloat-helpers.h"
#include "qemu/int128.h"
/*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point
@ -182,7 +183,9 @@ floatx80 int64_to_floatx80(int64_t, float_status *status);
float128 int32_to_float128(int32_t, float_status *status);
float128 int64_to_float128(int64_t, float_status *status);
float128 int128_to_float128(Int128, float_status *status);
float128 uint64_to_float128(uint64_t, float_status *status);
float128 uint128_to_float128(Int128, float_status *status);
/*----------------------------------------------------------------------------
| Software half-precision conversion routines.
@ -1201,9 +1204,13 @@ floatx80 floatx80_default_nan(float_status *status);
int32_t float128_to_int32(float128, float_status *status);
int32_t float128_to_int32_round_to_zero(float128, float_status *status);
int64_t float128_to_int64(float128, float_status *status);
Int128 float128_to_int128(float128, float_status *status);
int64_t float128_to_int64_round_to_zero(float128, float_status *status);
Int128 float128_to_int128_round_to_zero(float128, float_status *status);
uint64_t float128_to_uint64(float128, float_status *status);
Int128 float128_to_uint128(float128, float_status *status);
uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
Int128 float128_to_uint128_round_to_zero(float128, float_status *status);
uint32_t float128_to_uint32(float128, float_status *status);
uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
float32 float128_to_float32(float128, float_status *status);

View File

@ -1,7 +1,7 @@
/*
* QEMU PowerPC PowerNV LPC controller
*
* Copyright (c) 2016, IBM Corporation.
* Copyright (c) 2016-2022, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,7 +20,6 @@
#ifndef PPC_PNV_LPC_H
#define PPC_PNV_LPC_H
#include "hw/ppc/pnv_psi.h"
#include "qom/object.h"
#define TYPE_PNV_LPC "pnv-lpc"
@ -84,15 +83,12 @@ struct PnvLpcController {
MemoryRegion xscom_regs;
/* PSI to generate interrupts */
PnvPsi *psi;
qemu_irq psi_irq;
};
struct PnvLpcClass {
DeviceClass parent_class;
int psi_irq;
DeviceRealize parent_realize;
};

View File

@ -1,7 +1,7 @@
/*
* QEMU PowerPC PowerNV Emulation of a few OCC related registers
*
* Copyright (c) 2015-2017, IBM Corporation.
* Copyright (c) 2015-2022, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,7 +20,6 @@
#ifndef PPC_PNV_OCC_H
#define PPC_PNV_OCC_H
#include "hw/ppc/pnv_psi.h"
#include "qom/object.h"
#define TYPE_PNV_OCC "pnv-occ"
@ -44,19 +43,17 @@ struct PnvOCC {
/* OCC Misc interrupt */
uint64_t occmisc;
PnvPsi *psi;
qemu_irq psi_irq;
MemoryRegion xscom_regs;
MemoryRegion sram_regs;
};
struct PnvOCCClass {
DeviceClass parent_class;
int xscom_size;
const MemoryRegionOps *xscom_ops;
int psi_irq;
};
#define PNV_OCC_SENSOR_DATA_BLOCK_BASE(i) \

View File

@ -1,7 +1,7 @@
/*
* QEMU PowerPC PowerNV Processor Service Interface (PSI) model
*
* Copyright (c) 2015-2017, IBM Corporation.
* Copyright (c) 2015-2022, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -79,13 +79,10 @@ struct PnvPsiClass {
uint64_t bar_mask;
const char *compat;
int compat_size;
void (*irq_set)(PnvPsi *psi, int, bool state);
};
/* The PSI and FSP interrupts are muxed on the same IRQ number */
typedef enum PnvPsiIrq {
PSIHB_IRQ_PSI, /* internal use only */
PSIHB_IRQ_FSP, /* internal use only */
PSIHB_IRQ_OCC,
PSIHB_IRQ_FSI,
@ -96,8 +93,6 @@ typedef enum PnvPsiIrq {
#define PSI_NUM_INTERRUPTS 6
void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state);
/* P9 PSI Interrupts */
#define PSIHB9_IRQ_PSI 0
#define PSIHB9_IRQ_OCC 1

View File

@ -99,11 +99,11 @@ enum {
ARCH_MAC99_U3,
};
#define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
#define FW_CFG_PPC_CLOCKFREQ (FW_CFG_ARCH_LOCAL + 0x04)
#define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
#define FW_CFG_PPC_CLOCKFREQ (FW_CFG_ARCH_LOCAL + 0x04)
#define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05)
#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06)
#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07)

View File

@ -745,6 +745,7 @@ void push_sregs_to_kvm_pr(SpaprMachineState *spapr);
#define RTAS_DDW_PGSIZE_128M 0x20
#define RTAS_DDW_PGSIZE_256M 0x40
#define RTAS_DDW_PGSIZE_16G 0x80
#define RTAS_DDW_PGSIZE_2M 0x100
/* RTAS tokens */
#define RTAS_TOKEN_BASE 0x2000

View File

@ -83,6 +83,11 @@ static inline Int128 int128_rshift(Int128 a, int n)
return a >> n;
}
static inline Int128 int128_urshift(Int128 a, int n)
{
return (__uint128_t)a >> n;
}
static inline Int128 int128_lshift(Int128 a, int n)
{
return a << n;
@ -299,6 +304,20 @@ static inline Int128 int128_rshift(Int128 a, int n)
}
}
static inline Int128 int128_urshift(Int128 a, int n)
{
uint64_t h = a.hi;
if (!n) {
return a;
}
h = h >> (n & 63);
if (n >= 64) {
return int128_make64(h);
} else {
return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
}
}
static inline Int128 int128_lshift(Int128 a, int n)
{
uint64_t l = a.lo << (n & 63);
@ -412,5 +431,7 @@ static inline void bswap128s(Int128 *s)
}
#define UINT128_MAX int128_make128(~0LL, ~0LL)
#define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
#define INT128_MIN int128_make128(0, INT64_MIN)
#endif /* INT128_H */

Binary file not shown.

@ -1 +1 @@
Subproject commit 820d43c0a7751e75a8830561f35535dfffd522bd
Subproject commit 24a7eb35966d93455520bc2debdd7954314b638b

View File

@ -6457,6 +6457,7 @@ static void init_proc_POWER10(CPUPPCState *env)
register_power5p_common_sprs(env);
register_power5p_lpar_sprs(env);
register_power5p_ear_sprs(env);
register_power5p_tb_sprs(env);
register_power6_common_sprs(env);
register_power6_dbg_sprs(env);
register_power8_tce_address_control_sprs(env);
@ -6467,6 +6468,7 @@ static void init_proc_POWER10(CPUPPCState *env)
register_power8_pmu_user_sprs(env);
register_power8_tm_sprs(env);
register_power8_pspb_sprs(env);
register_power8_dpdes_sprs(env);
register_vtb_sprs(env);
register_power8_ic_sprs(env);
register_power8_book4_sprs(env);

View File

@ -2925,6 +2925,27 @@ VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), 0x80000000U)
VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2 * i), VsrD(i), 0ULL)
VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U)
#define VSX_CVT_FP_TO_INT128(op, tp, rnan) \
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
ppc_vsr_t t; \
int flags; \
\
helper_reset_fpstatus(env); \
t.s128 = float128_to_##tp##_round_to_zero(xb->f128, &env->fp_status); \
flags = get_float_exception_flags(&env->fp_status); \
if (unlikely(flags & float_flag_invalid)) { \
t.VsrD(0) = float_invalid_cvt(env, flags, t.VsrD(0), rnan, 0, GETPC());\
t.VsrD(1) = -(t.VsrD(0) & 1); \
} \
\
*xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_CVT_FP_TO_INT128(XSCVQPUQZ, uint128, 0)
VSX_CVT_FP_TO_INT128(XSCVQPSQZ, int128, 0x8000000000000000ULL);
/*
* Likewise, except that the result is duplicated into both subwords.
* Power ISA v3.1 has Programming Notes for these insns:
@ -3058,6 +3079,18 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
VSX_CVT_INT_TO_FP2(xvcvsxdsp, int64, float32)
VSX_CVT_INT_TO_FP2(xvcvuxdsp, uint64, float32)
#define VSX_CVT_INT128_TO_FP(op, tp) \
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)\
{ \
helper_reset_fpstatus(env); \
xt->f128 = tp##_to_float128(xb->s128, &env->fp_status); \
helper_compute_fprf_float128(env, xt->f128); \
do_float_check_status(env, GETPC()); \
}
VSX_CVT_INT128_TO_FP(XSCVUQQP, uint128);
VSX_CVT_INT128_TO_FP(XSCVSQQP, int128);
/*
* VSX_CVT_INT_TO_FP_VECTOR - VSX integer to floating point conversion
* op - instruction mnemonic

View File

@ -388,6 +388,10 @@ DEF_HELPER_4(xscvqpsdz, void, env, i32, vsr, vsr)
DEF_HELPER_4(xscvqpswz, void, env, i32, vsr, vsr)
DEF_HELPER_4(xscvqpudz, void, env, i32, vsr, vsr)
DEF_HELPER_4(xscvqpuwz, void, env, i32, vsr, vsr)
DEF_HELPER_3(XSCVQPUQZ, void, env, vsr, vsr)
DEF_HELPER_3(XSCVQPSQZ, void, env, vsr, vsr)
DEF_HELPER_3(XSCVUQQP, void, env, vsr, vsr)
DEF_HELPER_3(XSCVSQQP, void, env, vsr, vsr)
DEF_HELPER_3(xscvhpdp, void, env, vsr, vsr)
DEF_HELPER_4(xscvsdqp, void, env, i32, vsr, vsr)
DEF_HELPER_3(xscvspdp, void, env, vsr, vsr)

View File

@ -91,6 +91,9 @@
@X_tp_a_bp_rc ...... ....0 ra:5 ....0 .......... rc:1 &X_rc rt=%x_frtp rb=%x_frbp
&X_tb rt rb
@X_tb ...... rt:5 ..... rb:5 .......... . &X_tb
&X_tb_rc rt rb rc:bool
@X_tb_rc ...... rt:5 ..... rb:5 .......... rc:1 &X_tb_rc
@ -692,6 +695,10 @@ XSCMPGTQP 111111 ..... ..... ..... 0011100100 - @X
## VSX Binary Floating-Point Convert Instructions
XSCVQPDP 111111 ..... 10100 ..... 1101000100 . @X_tb_rc
XSCVQPUQZ 111111 ..... 00000 ..... 1101000100 - @X_tb
XSCVQPSQZ 111111 ..... 01000 ..... 1101000100 - @X_tb
XSCVUQQP 111111 ..... 00011 ..... 1101000100 - @X_tb
XSCVSQQP 111111 ..... 01011 ..... 1101000100 - @X_tb
XVCVBF16SPN 111100 ..... 10000 ..... 111011011 .. @XX2
XVCVSPBF16 111100 ..... 10001 ..... 111011011 .. @XX2

View File

@ -1680,7 +1680,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
break;
#if defined(TARGET_PPC64)
case KVM_EXIT_PAPR_HCALL:
trace_kvm_handle_papr_hcall();
trace_kvm_handle_papr_hcall(run->papr_hcall.nr);
run->papr_hcall.ret = spapr_hypercall(cpu,
run->papr_hcall.nr,
run->papr_hcall.args);

View File

@ -23,7 +23,7 @@ kvm_failed_get_vpa(void) "Warning: Unable to get VPA information from KVM"
kvm_handle_dcr_write(void) "handle dcr write"
kvm_handle_dcr_read(void) "handle dcr read"
kvm_handle_halt(void) "handle halt"
kvm_handle_papr_hcall(void) "handle PAPR hypercall"
kvm_handle_papr_hcall(uint64_t hcall) "0x%" PRIx64
kvm_handle_epr(void) "handle epr"
kvm_handle_watchdog_expiry(void) "handle watchdog expiry"
kvm_handle_debug_exception(void) "handle debug exception"

View File

@ -838,6 +838,28 @@ static bool trans_XSCVQPDP(DisasContext *ctx, arg_X_tb_rc *a)
return true;
}
static bool do_helper_env_X_tb(DisasContext *ctx, arg_X_tb *a,
void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr))
{
TCGv_ptr xt, xb;
REQUIRE_INSNS_FLAGS2(ctx, ISA310);
REQUIRE_VSX(ctx);
xt = gen_avr_ptr(a->rt);
xb = gen_avr_ptr(a->rb);
gen_helper(cpu_env, xt, xb);
tcg_temp_free_ptr(xt);
tcg_temp_free_ptr(xb);
return true;
}
TRANS(XSCVUQQP, do_helper_env_X_tb, gen_helper_XSCVUQQP)
TRANS(XSCVSQQP, do_helper_env_X_tb, gen_helper_XSCVSQQP)
TRANS(XSCVQPUQZ, do_helper_env_X_tb, gen_helper_XSCVQPUQZ)
TRANS(XSCVQPSQZ, do_helper_env_X_tb, gen_helper_XSCVQPSQZ)
#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \
static void gen_##name(DisasContext *ctx) \
{ \

View File

@ -206,6 +206,55 @@ static void test_rshift(void)
test_rshift_one(0xFFFE8000U, 0, 0xFFFFFFFFFFFFFFFEULL, 0x8000000000000000ULL);
}
static void __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
test_urshift_one(uint32_t x, int n, uint64_t h, uint64_t l)
{
Int128 a = expand(x);
Int128 r = int128_urshift(a, n);
g_assert_cmpuint(int128_getlo(r), ==, l);
g_assert_cmpuint(int128_gethi(r), ==, h);
}
static void test_urshift(void)
{
test_urshift_one(0x00010000U, 64, 0x0000000000000000ULL,
0x0000000000000001ULL);
test_urshift_one(0x80010000U, 64, 0x0000000000000000ULL,
0x8000000000000001ULL);
test_urshift_one(0x7FFE0000U, 64, 0x0000000000000000ULL,
0x7FFFFFFFFFFFFFFEULL);
test_urshift_one(0xFFFE0000U, 64, 0x0000000000000000ULL,
0xFFFFFFFFFFFFFFFEULL);
test_urshift_one(0x00010000U, 60, 0x0000000000000000ULL,
0x0000000000000010ULL);
test_urshift_one(0x80010000U, 60, 0x0000000000000008ULL,
0x0000000000000010ULL);
test_urshift_one(0x00018000U, 60, 0x0000000000000000ULL,
0x0000000000000018ULL);
test_urshift_one(0x80018000U, 60, 0x0000000000000008ULL,
0x0000000000000018ULL);
test_urshift_one(0x7FFE0000U, 60, 0x0000000000000007ULL,
0xFFFFFFFFFFFFFFE0ULL);
test_urshift_one(0xFFFE0000U, 60, 0x000000000000000FULL,
0xFFFFFFFFFFFFFFE0ULL);
test_urshift_one(0x7FFE8000U, 60, 0x0000000000000007ULL,
0xFFFFFFFFFFFFFFE8ULL);
test_urshift_one(0xFFFE8000U, 60, 0x000000000000000FULL,
0xFFFFFFFFFFFFFFE8ULL);
test_urshift_one(0x00018000U, 0, 0x0000000000000001ULL,
0x8000000000000000ULL);
test_urshift_one(0x80018000U, 0, 0x8000000000000001ULL,
0x8000000000000000ULL);
test_urshift_one(0x7FFE0000U, 0, 0x7FFFFFFFFFFFFFFEULL,
0x0000000000000000ULL);
test_urshift_one(0xFFFE0000U, 0, 0xFFFFFFFFFFFFFFFEULL,
0x0000000000000000ULL);
test_urshift_one(0x7FFE8000U, 0, 0x7FFFFFFFFFFFFFFEULL,
0x8000000000000000ULL);
test_urshift_one(0xFFFE8000U, 0, 0xFFFFFFFFFFFFFFFEULL,
0x8000000000000000ULL);
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
@ -219,5 +268,6 @@ int main(int argc, char **argv)
g_test_add_func("/int128/int128_ge", test_ge);
g_test_add_func("/int128/int128_gt", test_gt);
g_test_add_func("/int128/int128_rshift", test_rshift);
g_test_add_func("/int128/int128_urshift", test_urshift);
return g_test_run();
}