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); 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, static int32_t floatx80_to_int32_scalbn(floatx80 a, FloatRoundMode rmode,
int scale, float_status *s) 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); 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) int32_t floatx80_to_int32(floatx80 a, float_status *s)
{ {
return floatx80_to_int32_scalbn(a, s->float_rounding_mode, 0, 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); 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) 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); 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); 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) uint8_t float16_to_uint8(float16 a, float_status *s)
{ {
return float16_to_uint8_scalbn(a, s->float_rounding_mode, 0, 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); 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) 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); 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); 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) uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
{ {
return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, 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); 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) float128 int64_to_float128(int64_t a, float_status *status)
{ {
FloatParts128 p; FloatParts128 p;
@ -3969,6 +4127,31 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
return float128_round_pack_canonical(&p, 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 * 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); error_propagate(errp, local_err);
return; return;
} }
pci_config_set_interrupt_pin(pci->config, 0);
} }
static void pnv_phb3_root_port_class_init(ObjectClass *klass, void *data) 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_word(conf + PCI_PREF_MEMORY_LIMIT, 0xfff1);
pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */ pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */
pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0xffffffff); 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) 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)); msix_notify(dev, pcie_cap_flags_get_vector(dev));
} else if (msi_enabled(dev)) { } else if (msi_enabled(dev)) {
msi_notify(dev, pcie_cap_flags_get_vector(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); 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) static void hotplug_event_clear(PCIDevice *dev)
{ {
hotplug_event_update_event_status(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); 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)); msix_notify(dev, pcie_aer_root_get_vector(dev));
} else if (msi_enabled(dev)) { } else if (msi_enabled(dev)) {
msi_notify(dev, pcie_aer_root_get_vector(dev)); msi_notify(dev, pcie_aer_root_get_vector(dev));
} else { } else if (pci_intx(dev) != -1) {
pci_irq_assert(dev); 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) static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
{ {
Pnv8Chip *chip8 = PNV8_CHIP(chip); 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); return pnv_lpc_isa_create(&chip8->lpc, true, errp);
} }
static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp) static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
{ {
Pnv8Chip *chip8 = PNV8_CHIP(chip); 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); return pnv_lpc_isa_create(&chip8->lpc, false, errp);
} }
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp) static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
{ {
Pnv9Chip *chip9 = PNV9_CHIP(chip); 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); return pnv_lpc_isa_create(&chip9->lpc, false, errp);
} }
static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp) static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
{ {
Pnv10Chip *chip10 = PNV10_CHIP(chip); 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); 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); &PNV_PSI(psi8)->xscom_regs);
/* Create LPC controller */ /* Create LPC controller */
object_property_set_link(OBJECT(&chip8->lpc), "psi", OBJECT(&chip8->psi),
&error_abort);
qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal); qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs); 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 */ /* 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)) { if (!qdev_realize(DEVICE(&chip8->occ), NULL, errp)) {
return; return;
} }
pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs); 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 */ /* OCC SRAM model */
memory_region_add_subregion(get_system_memory(), PNV_OCC_SENSOR_BASE(chip), 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); &PNV_PSI(psi9)->xscom_regs);
/* LPC */ /* LPC */
object_property_set_link(OBJECT(&chip9->lpc), "psi", OBJECT(&chip9->psi),
&error_abort);
if (!qdev_realize(DEVICE(&chip9->lpc), NULL, errp)) { if (!qdev_realize(DEVICE(&chip9->lpc), NULL, errp)) {
return; return;
} }
@ -1520,12 +1528,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
(uint64_t) PNV9_LPCM_BASE(chip)); (uint64_t) PNV9_LPCM_BASE(chip));
/* Create the simplified OCC model */ /* 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)) { if (!qdev_realize(DEVICE(&chip9->occ), NULL, errp)) {
return; return;
} }
pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs); 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 */ /* OCC SRAM model */
memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip), 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); &PNV_PSI(&chip10->psi)->xscom_regs);
/* LPC */ /* LPC */
object_property_set_link(OBJECT(&chip10->lpc), "psi",
OBJECT(&chip10->psi), &error_abort);
if (!qdev_realize(DEVICE(&chip10->lpc), NULL, errp)) { if (!qdev_realize(DEVICE(&chip10->lpc), NULL, errp)) {
return; return;
} }
@ -1725,13 +1731,13 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
(uint64_t) PNV10_LPCM_BASE(chip)); (uint64_t) PNV10_LPCM_BASE(chip));
/* Create the simplified OCC model */ /* 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)) { if (!qdev_realize(DEVICE(&chip10->occ), NULL, errp)) {
return; return;
} }
pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE, pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
&chip10->occ.xscom_regs); &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 */ /* OCC SRAM model */
memory_region_add_subregion(get_system_memory(), 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) static void pnv_lpc_eval_irqs(PnvLpcController *lpc)
{ {
bool lpc_to_opb_irq = false; bool lpc_to_opb_irq = false;
PnvLpcClass *plc = PNV_LPC_GET_CLASS(lpc);
/* Update LPC controller to OPB line */ /* Update LPC controller to OPB line */
if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) { 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; lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask;
/* Reflect the interrupt */ /* 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) 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; xdc->dt_xscom = pnv_lpc_dt_xscom;
plc->psi_irq = PSIHB_IRQ_LPC_I2C;
device_class_set_parent_realize(dc, pnv_lpc_power8_realize, device_class_set_parent_realize(dc, pnv_lpc_power8_realize,
&plc->parent_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"; dc->desc = "PowerNV LPC Controller POWER9";
plc->psi_irq = PSIHB9_IRQ_LPCHC;
device_class_set_parent_realize(dc, pnv_lpc_power9_realize, device_class_set_parent_realize(dc, pnv_lpc_power9_realize,
&plc->parent_realize); &plc->parent_realize);
} }
@ -706,8 +701,6 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
{ {
PnvLpcController *lpc = PNV_LPC(dev); PnvLpcController *lpc = PNV_LPC(dev);
assert(lpc->psi);
/* Reg inits */ /* Reg inits */
lpc->lpc_hc_fw_rd_acc_size = LPC_HC_FW_RD_4B; 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); "lpc-hc", LPC_HC_REGS_OPB_SIZE);
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR, memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs); &lpc->lpc_hc_regs);
}
static Property pnv_lpc_properties[] = { qdev_init_gpio_out(DEVICE(dev), &lpc->psi_irq, 1);
DEFINE_PROP_LINK("psi", PnvLpcController, psi, TYPE_PNV_PSI, PnvPsi *), }
DEFINE_PROP_END_OF_LIST(),
};
static void pnv_lpc_class_init(ObjectClass *klass, void *data) 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->realize = pnv_lpc_realize;
dc->desc = "PowerNV LPC Controller"; dc->desc = "PowerNV LPC Controller";
device_class_set_props(dc, pnv_lpc_properties);
dc->user_creatable = false; 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) { 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 "qapi/error.h"
#include "qemu/log.h" #include "qemu/log.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "hw/ppc/pnv.h" #include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_xscom.h" #include "hw/ppc/pnv_xscom.h"
@ -51,13 +52,12 @@
static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val)
{ {
bool irq_state; bool irq_state;
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
val &= 0xffff000000000000ull; val &= 0xffff000000000000ull;
occ->occmisc = val; occ->occmisc = val;
irq_state = !!(val >> 63); 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, 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_size = PNV_XSCOM_OCC_SIZE;
poc->xscom_ops = &pnv_occ_power8_xscom_ops; poc->xscom_ops = &pnv_occ_power8_xscom_ops;
poc->psi_irq = PSIHB_IRQ_OCC;
} }
static const TypeInfo pnv_occ_power8_type_info = { 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)"; dc->desc = "PowerNV OCC Controller (POWER9)";
poc->xscom_size = PNV9_XSCOM_OCC_SIZE; poc->xscom_size = PNV9_XSCOM_OCC_SIZE;
poc->xscom_ops = &pnv_occ_power9_xscom_ops; poc->xscom_ops = &pnv_occ_power9_xscom_ops;
poc->psi_irq = PSIHB9_IRQ_OCC;
} }
static const TypeInfo pnv_occ_power9_type_info = { 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); PnvOCC *occ = PNV_OCC(dev);
PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ);
assert(occ->psi);
occ->occmisc = 0; occ->occmisc = 0;
/* XScom region for OCC registers */ /* 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, memory_region_init_io(&occ->sram_regs, OBJECT(dev), &pnv_occ_sram_ops,
occ, "occ-common-area", occ, "occ-common-area",
PNV_OCC_SENSOR_DATA_BLOCK_SIZE); PNV_OCC_SENSOR_DATA_BLOCK_SIZE);
}
static Property pnv_occ_properties[] = { qdev_init_gpio_out(DEVICE(dev), &occ->psi_irq, 1);
DEFINE_PROP_LINK("psi", PnvOCC, psi, TYPE_PNV_PSI, PnvPsi *), }
DEFINE_PROP_END_OF_LIST(),
};
static void pnv_occ_class_init(ObjectClass *klass, void *data) 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->realize = pnv_occ_realize;
dc->desc = "PowerNV OCC Controller"; dc->desc = "PowerNV OCC Controller";
device_class_set_props(dc, pnv_occ_properties);
dc->user_creatable = false; 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. * FSP and PSI interrupts are muxed under the same number.
*/ */
static const uint32_t xivr_regs[] = { static const uint32_t xivr_regs[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_PSI] = PSIHB_XSCOM_XIVR_FSP,
[PSIHB_IRQ_FSP] = PSIHB_XSCOM_XIVR_FSP, [PSIHB_IRQ_FSP] = PSIHB_XSCOM_XIVR_FSP,
[PSIHB_IRQ_OCC] = PSIHB_XSCOM_XIVR_OCC, [PSIHB_IRQ_OCC] = PSIHB_XSCOM_XIVR_OCC,
[PSIHB_IRQ_FSI] = PSIHB_XSCOM_XIVR_FSI, [PSIHB_IRQ_FSI] = PSIHB_XSCOM_XIVR_FSI,
@ -194,8 +193,7 @@ static const uint32_t xivr_regs[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_XSCOM_XIVR_EXT, [PSIHB_IRQ_EXTERNAL] = PSIHB_XSCOM_XIVR_EXT,
}; };
static const uint32_t stat_regs[] = { static const uint32_t stat_regs[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_PSI] = PSIHB_XSCOM_CR,
[PSIHB_IRQ_FSP] = PSIHB_XSCOM_CR, [PSIHB_IRQ_FSP] = PSIHB_XSCOM_CR,
[PSIHB_IRQ_OCC] = PSIHB_XSCOM_IRQ_STAT, [PSIHB_IRQ_OCC] = PSIHB_XSCOM_IRQ_STAT,
[PSIHB_IRQ_FSI] = 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, [PSIHB_IRQ_EXTERNAL] = PSIHB_XSCOM_IRQ_STAT,
}; };
static const uint64_t stat_bits[] = { static const uint64_t stat_bits[PSI_NUM_INTERRUPTS] = {
[PSIHB_IRQ_PSI] = PSIHB_CR_PSI_IRQ,
[PSIHB_IRQ_FSP] = PSIHB_CR_FSP_IRQ, [PSIHB_IRQ_FSP] = PSIHB_CR_FSP_IRQ,
[PSIHB_IRQ_OCC] = PSIHB_IRQ_STAT_OCC, [PSIHB_IRQ_OCC] = PSIHB_IRQ_STAT_OCC,
[PSIHB_IRQ_FSI] = PSIHB_IRQ_STAT_FSI, [PSIHB_IRQ_FSI] = PSIHB_IRQ_STAT_FSI,
@ -214,23 +211,14 @@ static const uint64_t stat_bits[] = {
[PSIHB_IRQ_EXTERNAL] = PSIHB_IRQ_STAT_EXT, [PSIHB_IRQ_EXTERNAL] = PSIHB_IRQ_STAT_EXT,
}; };
void pnv_psi_irq_set(PnvPsi *psi, int irq, bool state) static void pnv_psi_power8_set_irq(void *opaque, int irq, int state)
{
PNV_PSI_GET_CLASS(psi)->irq_set(psi, irq, state);
}
static void pnv_psi_power8_irq_set(PnvPsi *psi, int irq, bool state)
{ {
PnvPsi *psi = opaque;
uint32_t xivr_reg; uint32_t xivr_reg;
uint32_t stat_reg; uint32_t stat_reg;
uint32_t src; uint32_t src;
bool masked; 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]; xivr_reg = xivr_regs[irq];
stat_reg = stat_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); 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); psi->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
/* XSCOM region for PSI registers */ /* 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_pcba = PNV_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE; ppc->xscom_size = PNV_XSCOM_PSIHB_SIZE;
ppc->bar_mask = PSIHB_BAR_MASK; ppc->bar_mask = PSIHB_BAR_MASK;
ppc->irq_set = pnv_psi_power8_irq_set;
ppc->compat = compat; ppc->compat = compat;
ppc->compat_size = sizeof(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)]; 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) { if (irq_method & PSIHB9_IRQ_METHOD) {
qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n"); qemu_log_mask(LOG_GUEST_ERROR, "PSI: LSI IRQ method no supported\n");
return; 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); 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 */ /* XSCOM region for PSI registers */
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops, pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_p9_xscom_ops,
psi, "xscom-psi", PNV9_XSCOM_PSIHB_SIZE); 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_pcba = PNV9_XSCOM_PSIHB_BASE;
ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE; ppc->xscom_size = PNV9_XSCOM_PSIHB_SIZE;
ppc->bar_mask = PSIHB9_BAR_MASK; ppc->bar_mask = PSIHB9_BAR_MASK;
ppc->irq_set = pnv_psi_power9_irq_set;
ppc->compat = compat; ppc->compat = compat;
ppc->compat_size = sizeof(compat); ppc->compat_size = sizeof(compat);

View File

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

View File

@ -3,9 +3,9 @@
* *
* Copyright 2007 IBM Corporation. * Copyright 2007 IBM Corporation.
* Authors: * Authors:
* Jerone Young <jyoung5@us.ibm.com> * Jerone Young <jyoung5@us.ibm.com>
* Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
* Hollis Blanchard <hollisb@us.ibm.com> * Hollis Blanchard <hollisb@us.ibm.com>
* *
* This work is licensed under the GNU GPL license version 2 or later. * 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; return H_FUNCTION;
} }
#ifndef CONFIG_TCG #ifdef 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 */
#define PRTS_MASK 0x1f #define PRTS_MASK 0x1f
static target_ulong h_set_ptbl(PowerPCCPU *cpu, static target_ulong h_set_ptbl(PowerPCCPU *cpu,
@ -1825,6 +1800,48 @@ out_restore_l1:
spapr_cpu->nested_host_state = NULL; 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) static void hypercall_register_types(void)
{ {
hypercall_register_softmmu(); 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_UPDATE_DT, h_update_dt);
spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl); hypercall_register_nested();
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);
} }
type_init(hypercall_register_types) 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) { 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" * This should be PARAM_ERROR, but Linux calls "ibm,nmi-interlock"
* for system reset interrupts, despite them not being interlocked. * for system reset interrupts, despite them not being interlocked.
* PowerVM silently ignores this and returns success here. Returning * PowerVM silently ignores this and returns success here. Returning
* failure causes Linux to print the error "FWNMI: nmi-interlock * failure causes Linux to print the error "FWNMI: nmi-interlock
* failed: -3", although no other apparent ill effects, this is a * failed: -3", although no other apparent ill effects, this is a
* regression for the user when enabling FWNMI. So for now, match * regression for the user when enabling FWNMI. So for now, match
* PowerVM. When most Linux clients are fixed, this could be * PowerVM. When most Linux clients are fixed, this could be
* changed. * changed.
*/ */
rtas_st(rets, 0, RTAS_OUT_SUCCESS); rtas_st(rets, 0, RTAS_OUT_SUCCESS);
return; 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[] = { const struct { int shift; uint32_t mask; } masks[] = {
{ 12, RTAS_DDW_PGSIZE_4K }, { 12, RTAS_DDW_PGSIZE_4K },
{ 16, RTAS_DDW_PGSIZE_64K }, { 16, RTAS_DDW_PGSIZE_64K },
{ 21, RTAS_DDW_PGSIZE_2M },
{ 24, RTAS_DDW_PGSIZE_16M }, { 24, RTAS_DDW_PGSIZE_16M },
{ 25, RTAS_DDW_PGSIZE_32M }, { 25, RTAS_DDW_PGSIZE_32M },
{ 26, RTAS_DDW_PGSIZE_64M }, { 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 nodeph, uint32_t pname,
uint32_t valaddr, uint32_t vallen) 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; uint32_t ret = PROM_ERROR;
int offset, rc; int offset, rc;
char trval[64] = ""; char trval[64] = "";

View File

@ -95,6 +95,7 @@ typedef enum {
#include "fpu/softfloat-types.h" #include "fpu/softfloat-types.h"
#include "fpu/softfloat-helpers.h" #include "fpu/softfloat-helpers.h"
#include "qemu/int128.h"
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point | 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 int32_to_float128(int32_t, float_status *status);
float128 int64_to_float128(int64_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 uint64_to_float128(uint64_t, float_status *status);
float128 uint128_to_float128(Int128, float_status *status);
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
| Software half-precision conversion routines. | 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(float128, float_status *status);
int32_t float128_to_int32_round_to_zero(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); 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); 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); 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); 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(float128, float_status *status);
uint32_t float128_to_uint32_round_to_zero(float128, float_status *status); uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
float32 float128_to_float32(float128, float_status *status); float32 float128_to_float32(float128, float_status *status);

View File

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

View File

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

View File

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

View File

@ -99,11 +99,11 @@ enum {
ARCH_MAC99_U3, ARCH_MAC99_U3,
}; };
#define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00) #define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01) #define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02) #define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03) #define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
#define FW_CFG_PPC_CLOCKFREQ (FW_CFG_ARCH_LOCAL + 0x04) #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_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05)
#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06) #define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06)
#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) #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_128M 0x20
#define RTAS_DDW_PGSIZE_256M 0x40 #define RTAS_DDW_PGSIZE_256M 0x40
#define RTAS_DDW_PGSIZE_16G 0x80 #define RTAS_DDW_PGSIZE_16G 0x80
#define RTAS_DDW_PGSIZE_2M 0x100
/* RTAS tokens */ /* RTAS tokens */
#define RTAS_TOKEN_BASE 0x2000 #define RTAS_TOKEN_BASE 0x2000

View File

@ -83,6 +83,11 @@ static inline Int128 int128_rshift(Int128 a, int n)
return a >> 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) static inline Int128 int128_lshift(Int128 a, int n)
{ {
return a << 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) static inline Int128 int128_lshift(Int128 a, int n)
{ {
uint64_t l = a.lo << (n & 63); 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 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 */ #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_common_sprs(env);
register_power5p_lpar_sprs(env); register_power5p_lpar_sprs(env);
register_power5p_ear_sprs(env); register_power5p_ear_sprs(env);
register_power5p_tb_sprs(env);
register_power6_common_sprs(env); register_power6_common_sprs(env);
register_power6_dbg_sprs(env); register_power6_dbg_sprs(env);
register_power8_tce_address_control_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_pmu_user_sprs(env);
register_power8_tm_sprs(env); register_power8_tm_sprs(env);
register_power8_pspb_sprs(env); register_power8_pspb_sprs(env);
register_power8_dpdes_sprs(env);
register_vtb_sprs(env); register_vtb_sprs(env);
register_power8_ic_sprs(env); register_power8_ic_sprs(env);
register_power8_book4_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(xvcvspuxds, 2, float32, uint64, VsrW(2 * i), VsrD(i), 0ULL)
VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U) 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. * Likewise, except that the result is duplicated into both subwords.
* Power ISA v3.1 has Programming Notes for these insns: * 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(xvcvsxdsp, int64, float32)
VSX_CVT_INT_TO_FP2(xvcvuxdsp, uint64, 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 * VSX_CVT_INT_TO_FP_VECTOR - VSX integer to floating point conversion
* op - instruction mnemonic * 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(xscvqpswz, void, env, i32, vsr, vsr)
DEF_HELPER_4(xscvqpudz, 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_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_3(xscvhpdp, void, env, vsr, vsr)
DEF_HELPER_4(xscvsdqp, void, env, i32, vsr, vsr) DEF_HELPER_4(xscvsdqp, void, env, i32, vsr, vsr)
DEF_HELPER_3(xscvspdp, void, env, 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_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 rb rc:bool
@X_tb_rc ...... rt:5 ..... rb:5 .......... rc:1 &X_tb_rc @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 ## VSX Binary Floating-Point Convert Instructions
XSCVQPDP 111111 ..... 10100 ..... 1101000100 . @X_tb_rc 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 XVCVBF16SPN 111100 ..... 10000 ..... 111011011 .. @XX2
XVCVSPBF16 111100 ..... 10001 ..... 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; break;
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
case KVM_EXIT_PAPR_HCALL: 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.ret = spapr_hypercall(cpu,
run->papr_hcall.nr, run->papr_hcall.nr,
run->papr_hcall.args); 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_write(void) "handle dcr write"
kvm_handle_dcr_read(void) "handle dcr read" kvm_handle_dcr_read(void) "handle dcr read"
kvm_handle_halt(void) "handle halt" 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_epr(void) "handle epr"
kvm_handle_watchdog_expiry(void) "handle watchdog expiry" kvm_handle_watchdog_expiry(void) "handle watchdog expiry"
kvm_handle_debug_exception(void) "handle debug exception" 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; 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) \ #define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \
static void gen_##name(DisasContext *ctx) \ static void gen_##name(DisasContext *ctx) \
{ \ { \

View File

@ -206,6 +206,55 @@ static void test_rshift(void)
test_rshift_one(0xFFFE8000U, 0, 0xFFFFFFFFFFFFFFFEULL, 0x8000000000000000ULL); 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) int main(int argc, char **argv)
{ {
g_test_init(&argc, &argv, NULL); 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_ge", test_ge);
g_test_add_func("/int128/int128_gt", test_gt); g_test_add_func("/int128/int128_gt", test_gt);
g_test_add_func("/int128/int128_rshift", test_rshift); g_test_add_func("/int128/int128_rshift", test_rshift);
g_test_add_func("/int128/int128_urshift", test_urshift);
return g_test_run(); return g_test_run();
} }