diff options
Diffstat (limited to 'hw/ppc/spapr_hcall.c')
-rw-r--r-- | hw/ppc/spapr_hcall.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index cff3b0f2b6..795207799d 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; |