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:
commit
aa9bbd8655
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"),
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user