2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
4 * Author: Yu Liu, <yu.liu@freescale.com>
7 * This file is derived from arch/powerpc/kvm/44x_emulate.c,
8 * by Hollis Blanchard <hollisb@us.ibm.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
15 #include <asm/kvm_ppc.h>
16 #include <asm/disassemble.h>
17 #include <asm/kvm_e500.h>
22 #define XOP_TLBIVAX 786
27 int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
28 unsigned int inst, int *advance)
30 int emulated = EMULATE_DONE;
34 switch (get_op(inst)) {
36 switch (get_xop(inst)) {
39 emulated = kvmppc_e500_emul_tlbre(vcpu);
43 emulated = kvmppc_e500_emul_tlbwe(vcpu);
48 emulated = kvmppc_e500_emul_tlbsx(vcpu,rb);
54 emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb);
58 emulated = EMULATE_FAIL;
64 emulated = EMULATE_FAIL;
67 if (emulated == EMULATE_FAIL)
68 emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
73 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
75 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
76 int emulated = EMULATE_DONE;
80 vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
81 vcpu->arch.pid = vcpu->arch.gpr[rs];
84 vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
86 vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
88 vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
90 vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
92 vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
94 vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
96 vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
98 vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
100 vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
102 vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
104 vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
106 vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
109 emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
113 /* extra exceptions */
115 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
118 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
121 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
124 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
128 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
134 int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
136 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
137 int emulated = EMULATE_DONE;
141 vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
143 vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
145 vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
147 vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
149 vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
151 vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
153 vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
155 vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
157 vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
159 vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
162 vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
163 vcpu->arch.gpr[rt] &= ~0xfffUL;
164 vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[0];
168 vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
169 vcpu->arch.gpr[rt] &= ~0xfffUL;
170 vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[1];
174 vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
176 vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
178 vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
181 vcpu->arch.gpr[rt] = 0; break;
183 /* extra exceptions */
185 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
188 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
191 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
194 vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
197 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);