ppc patch queue for 2023-05-28:

This queue includes several assorted fixes for PowerPC SPR
 emulation, a change in the default Pegasos2 CPU, the addition
 of AIL mode 3 for spapr, a PIC->CPU interrupt fix for prep and
 performance enhancements in fpu_helper.c.
 -----BEGIN PGP SIGNATURE-----
 
 iIwEABYKADQWIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCZHOFiRYcZGFuaWVsaGI0
 MTNAZ21haWwuY29tAAoJEDzZypbeAzFkVZ0BAMV+9RlHKRlldOSPMEWCWo6hmA/U
 9SMyJsZPY3OpDbE3AP9XOQR1boqyT5MJXoeOUq1OLlFm6mY7UA300kBZ7wxVCw==
 =IGNT
 -----END PGP SIGNATURE-----

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

ppc patch queue for 2023-05-28:

This queue includes several assorted fixes for PowerPC SPR
emulation, a change in the default Pegasos2 CPU, the addition
of AIL mode 3 for spapr, a PIC->CPU interrupt fix for prep and
performance enhancements in fpu_helper.c.

# -----BEGIN PGP SIGNATURE-----
#
# iIwEABYKADQWIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCZHOFiRYcZGFuaWVsaGI0
# MTNAZ21haWwuY29tAAoJEDzZypbeAzFkVZ0BAMV+9RlHKRlldOSPMEWCWo6hmA/U
# 9SMyJsZPY3OpDbE3AP9XOQR1boqyT5MJXoeOUq1OLlFm6mY7UA300kBZ7wxVCw==
# =IGNT
# -----END PGP SIGNATURE-----
# gpg: Signature made Sun 28 May 2023 09:47:05 AM PDT
# gpg:                using EDDSA key 17EBFF9923D01800AF2838193CD9CA96DE033164
# gpg:                issuer "danielhb413@gmail.com"
# gpg: Good signature from "Daniel Henrique Barboza <danielhb413@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 17EB FF99 23D0 1800 AF28  3819 3CD9 CA96 DE03 3164

* tag 'pull-ppc-20230528' of https://gitlab.com/danielhb/qemu:
  ppc/pegasos2: Change default CPU to 7457
  target/ppc: Add POWER9 DD2.2 model
  target/ppc: Merge COMPUTE_CLASS and COMPUTE_FPRF
  pnv_lpc: disable reentrancy detection for lpc-hc
  target/ppc: Use SMT4 small core chip type in POWER9/10 PVRs
  hw/ppc/prep: Fix wiring of PIC -> CPU interrupt
  spapr: Add SPAPR_CAP_AIL_MODE_3 for AIL mode 3 support for H_SET_MODE hcall
  target/ppc: Alignment faults do not set DSISR in ISA v3.0 onward
  target/ppc: Fix width of some 32-bit SPRs
  target/ppc: Fix fallback to MFSS for MFFS* instructions on pre 3.0 ISAs

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-05-29 14:31:52 -07:00
commit aa9bbd8655
26 changed files with 201 additions and 129 deletions

View File

@ -524,7 +524,7 @@ static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_IDE;
mc->default_boot_order = "cd";
mc->default_display = "std";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9");
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2");
mc->default_ram_id = "pegasos2.ram";
mc->default_ram_size = 512 * MiB;

View File

@ -2171,7 +2171,7 @@ static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
};
mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
xfc->match_nvt = pnv_match_nvt;

View File

@ -348,7 +348,7 @@ static const TypeInfo pnv_core_infos[] = {
DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.2"),
DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
};

View File

@ -734,10 +734,13 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp)
/* Create MMIO regions for LPC HC and OPB registers */
memory_region_init_io(&lpc->opb_master_regs, OBJECT(dev), &opb_master_ops,
lpc, "lpc-opb-master", LPC_OPB_REGS_OPB_SIZE);
lpc->opb_master_regs.disable_reentrancy_guard = true;
memory_region_add_subregion(&lpc->opb_mr, LPC_OPB_REGS_OPB_ADDR,
&lpc->opb_master_regs);
memory_region_init_io(&lpc->lpc_hc_regs, OBJECT(dev), &lpc_hc_ops, lpc,
"lpc-hc", LPC_HC_REGS_OPB_SIZE);
/* xscom writes to lpc-hc. As such mark lpc-hc re-entrancy safe */
lpc->lpc_hc_regs.disable_reentrancy_guard = true;
memory_region_add_subregion(&lpc->opb_mr, LPC_HC_REGS_OPB_ADDR,
&lpc->lpc_hc_regs);

View File

@ -271,9 +271,11 @@ static void ibm_40p_init(MachineState *machine)
}
/* PCI -> ISA bridge */
i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378"));
i82378_dev = DEVICE(pci_new(PCI_DEVFN(11, 0), "i82378"));
qdev_connect_gpio_out(i82378_dev, 0,
qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT));
qdev_realize_and_unref(i82378_dev, BUS(pci_bus), &error_fatal);
sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(i82378_dev, 15));
isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0"));

View File

@ -4631,7 +4631,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->dr_lmb_enabled = true;
smc->update_dt_enabled = true;
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.2");
mc->has_hotpluggable_cpus = true;
mc->nvdimm_supported = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
@ -4673,6 +4673,13 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
smc->default_caps.caps[SPAPR_CAP_RPT_INVALIDATE] = SPAPR_CAP_OFF;
/*
* This cap specifies whether the AIL 3 mode for
* H_SET_RESOURCE is supported. The default is modified
* by default_caps_with_cpu().
*/
smc->default_caps.caps[SPAPR_CAP_AIL_MODE_3] = SPAPR_CAP_ON;
spapr_caps_add_properties(smc);
smc->irq = &spapr_irq_dual;
smc->dr_phb_enabled = true;

View File

@ -614,6 +614,33 @@ static void cap_rpt_invalidate_apply(SpaprMachineState *spapr,
}
}
static void cap_ail_mode_3_apply(SpaprMachineState *spapr,
uint8_t val, Error **errp)
{
ERRP_GUARD();
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
if (!val) {
return;
}
if (tcg_enabled()) {
/* AIL-3 is only supported on POWER8 and above CPUs. */
if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
error_setg(errp, "TCG only supports cap-ail-mode-3 on POWER8 and later CPUs");
error_append_hint(errp, "Try appending -machine cap-ail-mode-3=off\n");
return;
}
} else if (kvm_enabled()) {
if (!kvmppc_supports_ail_3()) {
error_setg(errp, "KVM implementation does not support cap-ail-mode-3");
error_append_hint(errp, "Try appending -machine cap-ail-mode-3=off\n");
return;
}
}
}
SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
[SPAPR_CAP_HTM] = {
.name = "htm",
@ -731,6 +758,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
.type = "bool",
.apply = cap_rpt_invalidate_apply,
},
[SPAPR_CAP_AIL_MODE_3] = {
.name = "ail-mode-3",
.description = "Alternate Interrupt Location (AIL) mode 3 support",
.index = SPAPR_CAP_AIL_MODE_3,
.get = spapr_cap_get_bool,
.set = spapr_cap_set_bool,
.type = "bool",
.apply = cap_ail_mode_3_apply,
},
};
static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
@ -750,6 +786,7 @@ static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr,
0, spapr->max_compat_pvr)) {
caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN;
caps.caps[SPAPR_CAP_AIL_MODE_3] = SPAPR_CAP_OFF;
}
if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_06_PLUS,

View File

@ -390,6 +390,7 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v1.0"),
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
#ifdef CONFIG_KVM

View File

@ -817,30 +817,32 @@ static target_ulong h_set_mode_resource_le(PowerPCCPU *cpu,
}
static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong mflags,
target_ulong value1,
target_ulong value2)
{
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
return H_P2;
}
if (value1) {
return H_P3;
}
if (value2) {
return H_P4;
}
if (mflags == 1) {
/* AIL=1 is reserved in POWER8/POWER9/POWER10 */
/*
* AIL-1 is not architected, and AIL-2 is not supported by QEMU spapr.
* It is supported for faithful emulation of bare metal systems, but for
* compatibility concerns we leave it out of the pseries machine.
*/
if (mflags != 0 && mflags != 3) {
return H_UNSUPPORTED_FLAG;
}
if (mflags == 2 && (pcc->insns_flags2 & PPC2_ISA310)) {
/* AIL=2 is reserved in POWER10 (ISA v3.1) */
return H_UNSUPPORTED_FLAG;
if (mflags == 3) {
if (!spapr_get_cap(spapr, SPAPR_CAP_AIL_MODE_3)) {
return H_UNSUPPORTED_FLAG;
}
}
spapr_set_all_lpcrs(mflags << LPCR_AIL_SHIFT, LPCR_AIL);
@ -859,7 +861,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr,
ret = h_set_mode_resource_le(cpu, spapr, args[0], args[2], args[3]);
break;
case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE:
ret = h_set_mode_resource_addr_trans_mode(cpu, args[0],
ret = h_set_mode_resource_addr_trans_mode(cpu, spapr, args[0],
args[2], args[3]);
break;
}

View File

@ -48,7 +48,7 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8,
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8NVL,
TYPE_PNV_CHIP_POWER8NVL)
#define TYPE_PNV_CHIP_POWER9 PNV_CHIP_TYPE_NAME("power9_v2.0")
#define TYPE_PNV_CHIP_POWER9 PNV_CHIP_TYPE_NAME("power9_v2.2")
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER9,
TYPE_PNV_CHIP_POWER9)

View File

@ -78,8 +78,10 @@ typedef enum {
#define SPAPR_CAP_FWNMI 0x0A
/* Support H_RPT_INVALIDATE */
#define SPAPR_CAP_RPT_INVALIDATE 0x0B
/* Support for AIL modes */
#define SPAPR_CAP_AIL_MODE_3 0x0C
/* Num Caps */
#define SPAPR_CAP_NUM (SPAPR_CAP_RPT_INVALIDATE + 1)
#define SPAPR_CAP_NUM (SPAPR_CAP_AIL_MODE_3 + 1)
/*
* Capability Values

View File

@ -732,6 +732,8 @@
"POWER9 v1.0")
POWERPC_DEF("power9_v2.0", CPU_POWERPC_POWER9_DD20, POWER9,
"POWER9 v2.0")
POWERPC_DEF("power9_v2.2", CPU_POWERPC_POWER9_DD22, POWER9,
"POWER9 v2.2")
POWERPC_DEF("power10_v1.0", CPU_POWERPC_POWER10_DD1, POWER10,
"POWER10 v1.0")
POWERPC_DEF("power10_v2.0", CPU_POWERPC_POWER10_DD20, POWER10,
@ -907,7 +909,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
{ "power8e", "power8e_v2.1" },
{ "power8", "power8_v2.0" },
{ "power8nvl", "power8nvl_v1.0" },
{ "power9", "power9_v2.0" },
{ "power9", "power9_v2.2" },
{ "power10", "power10_v2.0" },
#endif

View File

@ -348,11 +348,12 @@ enum {
CPU_POWERPC_POWER8NVL_BASE = 0x004C0000,
CPU_POWERPC_POWER8NVL_v10 = 0x004C0100,
CPU_POWERPC_POWER9_BASE = 0x004E0000,
CPU_POWERPC_POWER9_DD1 = 0x004E0100,
CPU_POWERPC_POWER9_DD1 = 0x004E1100,
CPU_POWERPC_POWER9_DD20 = 0x004E1200,
CPU_POWERPC_POWER9_DD22 = 0x004E1202,
CPU_POWERPC_POWER10_BASE = 0x00800000,
CPU_POWERPC_POWER10_DD1 = 0x00800100,
CPU_POWERPC_POWER10_DD20 = 0x00800200,
CPU_POWERPC_POWER10_DD1 = 0x00801100,
CPU_POWERPC_POWER10_DD20 = 0x00801200,
CPU_POWERPC_970_v22 = 0x00390202,
CPU_POWERPC_970FX_v10 = 0x00391100,
CPU_POWERPC_970FX_v20 = 0x003C0200,

View File

@ -5085,8 +5085,8 @@ static void register_book3s_altivec_sprs(CPUPPCState *env)
}
spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
&spr_read_generic, &spr_write_generic32,
KVM_REG_PPC_VRSAVE, 0x00000000);
}
@ -5120,7 +5120,7 @@ static void register_book3s_207_dbg_sprs(CPUPPCState *env)
spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0",
SPR_NOACCESS, SPR_NOACCESS,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
KVM_REG_PPC_DAWRX, 0x00000000);
spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
SPR_NOACCESS, SPR_NOACCESS,
@ -5376,7 +5376,7 @@ static void register_book3s_ids_sprs(CPUPPCState *env)
spr_register_hv(env, SPR_TSCR, "TSCR",
SPR_NOACCESS, SPR_NOACCESS,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
0x00000000);
spr_register_hv(env, SPR_HMER, "HMER",
SPR_NOACCESS, SPR_NOACCESS,
@ -5406,7 +5406,7 @@ static void register_book3s_ids_sprs(CPUPPCState *env)
spr_register_hv(env, SPR_MMCRC, "MMCRC",
SPR_NOACCESS, SPR_NOACCESS,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
0x00000000);
spr_register_hv(env, SPR_MMCRH, "MMCRH",
SPR_NOACCESS, SPR_NOACCESS,
@ -5441,7 +5441,7 @@ static void register_book3s_ids_sprs(CPUPPCState *env)
spr_register_hv(env, SPR_HDSISR, "HDSISR",
SPR_NOACCESS, SPR_NOACCESS,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
0x00000000);
spr_register_hv(env, SPR_HRMOR, "HRMOR",
SPR_NOACCESS, SPR_NOACCESS,
@ -5665,7 +5665,7 @@ static void register_power7_book4_sprs(CPUPPCState *env)
KVM_REG_PPC_ACOP, 0);
spr_register_kvm(env, SPR_BOOKS_PID, "PID",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
KVM_REG_PPC_PID, 0);
#endif
}
@ -5730,7 +5730,7 @@ static void register_power10_dexcr_sprs(CPUPPCState *env)
{
spr_register(env, SPR_DEXCR, "DEXCR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
0);
spr_register(env, SPR_UDEXCR, "DEXCR",
@ -5741,7 +5741,7 @@ static void register_power10_dexcr_sprs(CPUPPCState *env)
spr_register_hv(env, SPR_HDEXCR, "HDEXCR",
SPR_NOACCESS, SPR_NOACCESS,
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
0);
spr_register(env, SPR_UHDEXCR, "HDEXCR",
@ -6284,9 +6284,26 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best)
return false;
}
if ((pvr & 0x0f00) == (pcc->pvr & 0x0f00)) {
/* Major DD version matches to power9_v1.0 and power9_v2.0 */
if ((pvr & 0x0f00) != (pcc->pvr & 0x0f00)) {
/* Major DD version does not match */
return false;
}
if ((pvr & 0x0f00) == 0x100) {
/* DD1.x always matches power9_v1.0 */
return true;
} else if ((pvr & 0x0f00) == 0x200) {
if ((pvr & 0xf) < 2) {
/* DD2.0, DD2.1 match power9_v2.0 */
if ((pcc->pvr & 0xf) == 0) {
return true;
}
} else {
/* DD2.2, DD2.3 match power9_v2.2 */
if ((pcc->pvr & 0xf) == 2) {
return true;
}
}
}
return false;

View File

@ -1431,13 +1431,16 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
break;
}
case POWERPC_EXCP_ALIGN: /* Alignment exception */
/* Get rS/rD and rA from faulting opcode */
/*
* Note: the opcode fields will not be set properly for a
* direct store load/store, but nobody cares as nobody
* actually uses direct store segments.
*/
env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
/* Optional DSISR update was removed from ISA v3.0 */
if (!(env->insns_flags2 & PPC2_ISA300)) {
/* Get rS/rD and rA from faulting opcode */
/*
* Note: the opcode fields will not be set properly for a
* direct store load/store, but nobody cares as nobody
* actually uses direct store segments.
*/
env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
}
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
switch (env->error_code & ~0xF) {

View File

@ -141,62 +141,28 @@ static inline int ppc_float64_get_unbiased_exp(float64 f)
return ((f >> 52) & 0x7FF) - 1023;
}
/* Classify a floating-point number. */
enum {
is_normal = 1,
is_zero = 2,
is_denormal = 4,
is_inf = 8,
is_qnan = 16,
is_snan = 32,
is_neg = 64,
};
#define COMPUTE_CLASS(tp) \
static int tp##_classify(tp arg) \
{ \
int ret = tp##_is_neg(arg) * is_neg; \
if (unlikely(tp##_is_any_nan(arg))) { \
float_status dummy = { }; /* snan_bit_is_one = 0 */ \
ret |= (tp##_is_signaling_nan(arg, &dummy) \
? is_snan : is_qnan); \
} else if (unlikely(tp##_is_infinity(arg))) { \
ret |= is_inf; \
} else if (tp##_is_zero(arg)) { \
ret |= is_zero; \
} else if (tp##_is_zero_or_denormal(arg)) { \
ret |= is_denormal; \
} else { \
ret |= is_normal; \
} \
return ret; \
}
COMPUTE_CLASS(float16)
COMPUTE_CLASS(float32)
COMPUTE_CLASS(float64)
COMPUTE_CLASS(float128)
static void set_fprf_from_class(CPUPPCState *env, int class)
{
static const uint8_t fprf[6][2] = {
{ 0x04, 0x08 }, /* normalized */
{ 0x02, 0x12 }, /* zero */
{ 0x14, 0x18 }, /* denormalized */
{ 0x05, 0x09 }, /* infinity */
{ 0x11, 0x11 }, /* qnan */
{ 0x00, 0x00 }, /* snan -- flags are undefined */
};
bool isneg = class & is_neg;
env->fpscr &= ~FP_FPRF;
env->fpscr |= fprf[ctz32(class)][isneg] << FPSCR_FPRF;
}
#define COMPUTE_FPRF(tp) \
void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
{ \
set_fprf_from_class(env, tp##_classify(arg)); \
#define COMPUTE_FPRF(tp) \
void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
{ \
bool neg = tp##_is_neg(arg); \
target_ulong fprf; \
if (likely(tp##_is_normal(arg))) { \
fprf = neg ? 0x08 << FPSCR_FPRF : 0x04 << FPSCR_FPRF; \
} else if (tp##_is_zero(arg)) { \
fprf = neg ? 0x12 << FPSCR_FPRF : 0x02 << FPSCR_FPRF; \
} else if (tp##_is_zero_or_denormal(arg)) { \
fprf = neg ? 0x18 << FPSCR_FPRF : 0x14 << FPSCR_FPRF; \
} else if (tp##_is_infinity(arg)) { \
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
} else { \
float_status dummy = { }; /* snan_bit_is_one = 0 */ \
if (tp##_is_signaling_nan(arg, &dummy)) { \
fprf = 0x00 << FPSCR_FPRF; \
} else { \
fprf = 0x11 << FPSCR_FPRF; \
} \
} \
env->fpscr = (env->fpscr & ~FP_FPRF) | fprf; \
}
COMPUTE_FPRF(float16)

View File

@ -448,7 +448,7 @@ void register_non_embedded_sprs(CPUPPCState *env)
/* Exception processing */
spr_register_kvm(env, SPR_DSISR, "DSISR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic32,
KVM_REG_PPC_DSISR, 0x00000000);
spr_register_kvm(env, SPR_DAR, "DAR",
SPR_NOACCESS, SPR_NOACCESS,

View File

@ -390,13 +390,19 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi
### Move To/From FPSCR
MFFS 111111 ..... 00000 ----- 1001000111 . @X_t_rc
MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t
MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb
MFFSCDRN 111111 ..... 10100 ..... 1001000111 - @X_tb
MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2
MFFSCDRNI 111111 ..... 10101 --... 1001000111 - @X_imm3
MFFSL 111111 ..... 11000 ----- 1001000111 - @X_t
{
# Before Power ISA v3.0, MFFS bits 11~15 were reserved and should be ignored
MFFS_ISA207 111111 ..... ----- ----- 1001000111 . @X_t_rc
[
MFFS 111111 ..... 00000 ----- 1001000111 . @X_t_rc
MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t
MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb
MFFSCDRN 111111 ..... 10100 ..... 1001000111 - @X_tb
MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2
MFFSCDRNI 111111 ..... 10101 --... 1001000111 - @X_imm3
MFFSL 111111 ..... 11000 ----- 1001000111 - @X_t
]
}
### Decimal Floating-Point Arithmetic Instructions

View File

@ -88,6 +88,7 @@ static int cap_ppc_nested_kvm_hv;
static int cap_large_decr;
static int cap_fwnmi;
static int cap_rpt_invalidate;
static int cap_ail_mode_3;
static uint32_t debug_inst_opcode;
@ -152,6 +153,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
cap_rpt_invalidate = kvm_vm_check_extension(s, KVM_CAP_PPC_RPT_INVALIDATE);
cap_ail_mode_3 = kvm_vm_check_extension(s, KVM_CAP_PPC_AIL_MODE_3);
kvm_ppc_register_host_cpu_type();
return 0;
@ -2560,6 +2562,11 @@ int kvmppc_has_cap_rpt_invalidate(void)
return cap_rpt_invalidate;
}
bool kvmppc_supports_ail_3(void)
{
return cap_ail_mode_3;
}
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
{
uint32_t host_pvr = mfpvr();

View File

@ -76,6 +76,7 @@ int kvmppc_set_cap_nested_kvm_hv(int enable);
int kvmppc_get_cap_large_decr(void);
int kvmppc_enable_cap_large_decr(PowerPCCPU *cpu, int enable);
int kvmppc_has_cap_rpt_invalidate(void);
bool kvmppc_supports_ail_3(void);
int kvmppc_enable_hwrng(void);
int kvmppc_put_books_sregs(PowerPCCPU *cpu);
PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
@ -396,6 +397,11 @@ static inline int kvmppc_has_cap_rpt_invalidate(void)
return false;
}
static inline bool kvmppc_supports_ail_3(void)
{
return false;
}
static inline int kvmppc_enable_hwrng(void)
{
return -1;

View File

@ -190,13 +190,13 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val)
void helper_store_pidr(CPUPPCState *env, target_ulong val)
{
env->spr[SPR_BOOKS_PID] = val;
env->spr[SPR_BOOKS_PID] = (uint32_t)val;
tlb_flush(env_cpu(env));
}
void helper_store_lpidr(CPUPPCState *env, target_ulong val)
{
env->spr[SPR_LPIDR] = val;
env->spr[SPR_LPIDR] = (uint32_t)val;
/*
* We need to flush the TLB on LPID changes as we only tag HV vs

View File

@ -272,7 +272,7 @@ void helper_store_pmc(CPUPPCState *env, uint32_t sprn, uint64_t value)
{
pmu_update_cycles(env);
env->spr[sprn] = value;
env->spr[sprn] = (uint32_t)value;
pmc_update_overflow_timer(env, sprn);
}

View File

@ -81,6 +81,7 @@ void _spr_register(CPUPPCState *env, int num, const char *name,
void spr_noaccess(DisasContext *ctx, int gprn, int sprn);
void spr_read_generic(DisasContext *ctx, int gprn, int sprn);
void spr_write_generic(DisasContext *ctx, int sprn, int gprn);
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn);
void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn);
void spr_write_PMC(DisasContext *ctx, int sprn, int gprn);
@ -109,7 +110,6 @@ void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn);
void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn);
#ifndef CONFIG_USER_ONLY
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
void spr_write_clear(DisasContext *ctx, int sprn, int gprn);
void spr_access_nop(DisasContext *ctx, int sprn, int gprn);
void spr_read_decr(DisasContext *ctx, int gprn, int sprn);

View File

@ -411,19 +411,6 @@ void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
spr_store_dump_spr(sprn);
}
void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
{
spr_write_generic(ctx, sprn, gprn);
/*
* SPR_CTRL writes must force a new translation block,
* allowing the PMU to calculate the run latch events with
* more accuracy.
*/
ctx->base.is_jmp = DISAS_EXIT_UPDATE;
}
#if !defined(CONFIG_USER_ONLY)
void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
{
#ifdef TARGET_PPC64
@ -436,6 +423,19 @@ void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
#endif
}
void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
{
spr_write_generic32(ctx, sprn, gprn);
/*
* SPR_CTRL writes must force a new translation block,
* allowing the PMU to calculate the run latch events with
* more accuracy.
*/
ctx->base.is_jmp = DISAS_EXIT_UPDATE;
}
#if !defined(CONFIG_USER_ONLY)
void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
{
TCGv t0 = tcg_temp_new();

View File

@ -568,6 +568,22 @@ static void store_fpscr_masked(TCGv_i64 fpscr, uint64_t clear_mask,
gen_helper_store_fpscr(cpu_env, fpscr_masked, st_mask);
}
static bool trans_MFFS_ISA207(DisasContext *ctx, arg_X_t_rc *a)
{
if (!(ctx->insns_flags2 & PPC2_ISA300)) {
/*
* Before Power ISA v3.0, MFFS bits 11~15 were reserved, any instruction
* with OPCD=63 and XO=583 should be decoded as MFFS.
*/
return trans_MFFS(ctx, a);
}
/*
* For Power ISA v3.0+, return false and let the pattern group
* select the correct instruction.
*/
return false;
}
static bool trans_MFFS(DisasContext *ctx, arg_X_t_rc *a)
{
REQUIRE_FPU(ctx);
@ -584,7 +600,6 @@ static bool trans_MFFSCE(DisasContext *ctx, arg_X_t *a)
{
TCGv_i64 fpscr;
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
gen_reset_fpstatus();
@ -597,7 +612,6 @@ static bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a)
{
TCGv_i64 t1, fpscr;
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
t1 = tcg_temp_new_i64();
@ -614,7 +628,6 @@ static bool trans_MFFSCDRN(DisasContext *ctx, arg_X_tb *a)
{
TCGv_i64 t1, fpscr;
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
t1 = tcg_temp_new_i64();
@ -631,7 +644,6 @@ static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a)
{
TCGv_i64 t1, fpscr;
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
t1 = tcg_temp_new_i64();
@ -647,7 +659,6 @@ static bool trans_MFFSCDRNI(DisasContext *ctx, arg_X_imm3 *a)
{
TCGv_i64 t1, fpscr;
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
t1 = tcg_temp_new_i64();
@ -661,7 +672,6 @@ static bool trans_MFFSCDRNI(DisasContext *ctx, arg_X_imm3 *a)
static bool trans_MFFSL(DisasContext *ctx, arg_X_t *a)
{
REQUIRE_INSNS_FLAGS2(ctx, ISA300);
REQUIRE_FPU(ctx);
gen_reset_fpstatus();

View File

@ -175,8 +175,8 @@ static void test_spapr_cpu_unplug_request(void)
{
QTestState *qtest;
qtest = qtest_initf("-cpu power9_v2.0 -smp 1,maxcpus=2 "
"-device power9_v2.0-spapr-cpu-core,core-id=1,id=dev0");
qtest = qtest_initf("-cpu power9_v2.2 -smp 1,maxcpus=2 "
"-device power9_v2.2-spapr-cpu-core,core-id=1,id=dev0");
/* similar to test_pci_unplug_request */
process_device_remove(qtest, "dev0");