aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2014-06-04 22:51:05 +1000
committerAlexander Graf <agraf@suse.de>2014-06-16 13:24:45 +0200
commitd5ac4f543352c3412172fb72256137defb13a4b1 (patch)
tree3152964851f905c3fb93ff30889657ba03e74b4f /hw/ppc
parentc4015bbd502d670d88e5689e1143e36ea097c76f (diff)
downloadqemu-d5ac4f543352c3412172fb72256137defb13a4b1.zip
qemu-d5ac4f543352c3412172fb72256137defb13a4b1.tar.gz
qemu-d5ac4f543352c3412172fb72256137defb13a4b1.tar.bz2
spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE
This adds handling of the RESOURCE_ADDR_TRANS_MODE resource from the H_SET_MODE, for POWER8 (PowerISA 2.07) only. This defines AIL flags for LPCR special register. This changes @excp_prefix according to the mode, takes effect in TCG. This turns support of a new capability PPC2_ISA207S flag for TCG. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/ppc')
-rw-r--r--hw/ppc/spapr_hcall.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index cff3b0f..7952077 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -743,6 +743,49 @@ static target_ulong h_set_mode_resouce_le(PowerPCCPU *cpu,
return H_UNSUPPORTED_FLAG;
}
+static target_ulong h_set_mode_resouce_addr_trans_mode(PowerPCCPU *cpu,
+ target_ulong mflags,
+ target_ulong value1,
+ target_ulong value2)
+{
+ CPUState *cs;
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ target_ulong prefix;
+
+ if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
+ return H_P2;
+ }
+ if (value1) {
+ return H_P3;
+ }
+ if (value2) {
+ return H_P4;
+ }
+
+ switch (mflags) {
+ case H_SET_MODE_ADDR_TRANS_NONE:
+ prefix = 0;
+ break;
+ case H_SET_MODE_ADDR_TRANS_0001_8000:
+ prefix = 0x18000;
+ break;
+ case H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000:
+ prefix = 0xC000000000004000;
+ break;
+ default:
+ return H_UNSUPPORTED_FLAG;
+ }
+
+ CPU_FOREACH(cs) {
+ CPUPPCState *env = &POWERPC_CPU(cpu)->env;
+
+ set_spr(cs, SPR_LPCR, mflags << LPCR_AIL_SHIFT, LPCR_AIL);
+ env->excp_prefix = prefix;
+ }
+
+ return H_SUCCESS;
+}
+
static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
target_ulong opcode, target_ulong *args)
{
@@ -753,6 +796,10 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
case H_SET_MODE_RESOURCE_LE:
ret = h_set_mode_resouce_le(cpu, args[0], args[2], args[3]);
break;
+ case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE:
+ ret = h_set_mode_resouce_addr_trans_mode(cpu, args[0],
+ args[2], args[3]);
+ break;
}
return ret;