blob: c80794d097d33cd911791da6a66ff7475dca3c02 [file] [log] [blame]
Hollis Blanchardbc8080c2009-01-03 16:23:10 -06001/*
Scott Wood5ce941e2011-04-27 17:24:21 -05002 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
Hollis Blanchardbc8080c2009-01-03 16:23:10 -06003 *
4 * Author: Yu Liu, <yu.liu@freescale.com>
5 *
6 * Description:
7 * This file is derived from arch/powerpc/kvm/44x_emulate.c,
8 * by Hollis Blanchard <hollisb@us.ibm.com>.
9 *
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.
13 */
14
15#include <asm/kvm_ppc.h>
16#include <asm/disassemble.h>
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060017
18#include "booke.h"
Scott Wood29a5a6f2011-12-20 15:34:29 +000019#include "e500.h"
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060020
21#define XOP_TLBIVAX 786
22#define XOP_TLBSX 914
23#define XOP_TLBRE 946
24#define XOP_TLBWE 978
25
26int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
27 unsigned int inst, int *advance)
28{
29 int emulated = EMULATE_DONE;
30 int ra;
31 int rb;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060032
33 switch (get_op(inst)) {
34 case 31:
35 switch (get_xop(inst)) {
36
37 case XOP_TLBRE:
38 emulated = kvmppc_e500_emul_tlbre(vcpu);
39 break;
40
41 case XOP_TLBWE:
42 emulated = kvmppc_e500_emul_tlbwe(vcpu);
43 break;
44
45 case XOP_TLBSX:
46 rb = get_rb(inst);
47 emulated = kvmppc_e500_emul_tlbsx(vcpu,rb);
48 break;
49
50 case XOP_TLBIVAX:
51 ra = get_ra(inst);
52 rb = get_rb(inst);
53 emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb);
54 break;
55
56 default:
57 emulated = EMULATE_FAIL;
58 }
59
60 break;
61
62 default:
63 emulated = EMULATE_FAIL;
64 }
65
66 if (emulated == EMULATE_FAIL)
67 emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
68
69 return emulated;
70}
71
72int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
73{
74 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
75 int emulated = EMULATE_DONE;
Alexander Graf8e5b26b2010-01-08 02:58:01 +010076 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060077
78 switch (sprn) {
79 case SPRN_PID:
Scott Wood5ce941e2011-04-27 17:24:21 -050080 kvmppc_set_pid(vcpu, spr_val);
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060081 break;
82 case SPRN_PID1:
Liu Yudd9ebf1f2011-06-14 18:35:14 -050083 if (spr_val != 0)
84 return EMULATE_FAIL;
Alexander Graf8e5b26b2010-01-08 02:58:01 +010085 vcpu_e500->pid[1] = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060086 case SPRN_PID2:
Liu Yudd9ebf1f2011-06-14 18:35:14 -050087 if (spr_val != 0)
88 return EMULATE_FAIL;
Alexander Graf8e5b26b2010-01-08 02:58:01 +010089 vcpu_e500->pid[2] = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060090 case SPRN_MAS0:
Scott Woodb5904972011-11-08 18:23:30 -060091 vcpu->arch.shared->mas0 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060092 case SPRN_MAS1:
Scott Woodb5904972011-11-08 18:23:30 -060093 vcpu->arch.shared->mas1 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060094 case SPRN_MAS2:
Scott Woodb5904972011-11-08 18:23:30 -060095 vcpu->arch.shared->mas2 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -060096 case SPRN_MAS3:
Scott Woodb5904972011-11-08 18:23:30 -060097 vcpu->arch.shared->mas7_3 &= ~(u64)0xffffffff;
98 vcpu->arch.shared->mas7_3 |= spr_val;
Scott Wooddc83b8b2011-08-18 15:25:21 -050099 break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600100 case SPRN_MAS4:
Scott Woodb5904972011-11-08 18:23:30 -0600101 vcpu->arch.shared->mas4 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600102 case SPRN_MAS6:
Scott Woodb5904972011-11-08 18:23:30 -0600103 vcpu->arch.shared->mas6 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600104 case SPRN_MAS7:
Scott Woodb5904972011-11-08 18:23:30 -0600105 vcpu->arch.shared->mas7_3 &= (u64)0xffffffff;
106 vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32;
Scott Wooddc83b8b2011-08-18 15:25:21 -0500107 break;
Liu Yud86be072010-01-22 18:50:29 +0800108 case SPRN_L1CSR0:
109 vcpu_e500->l1csr0 = spr_val;
110 vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
111 break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600112 case SPRN_L1CSR1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100113 vcpu_e500->l1csr1 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600114 case SPRN_HID0:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100115 vcpu_e500->hid0 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600116 case SPRN_HID1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100117 vcpu_e500->hid1 = spr_val; break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600118
Liu Yub0a18352009-02-17 16:52:08 +0800119 case SPRN_MMUCSR0:
120 emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100121 spr_val);
Liu Yub0a18352009-02-17 16:52:08 +0800122 break;
123
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600124 /* extra exceptions */
125 case SPRN_IVOR32:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100126 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600127 break;
128 case SPRN_IVOR33:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100129 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val;
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600130 break;
131 case SPRN_IVOR34:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100132 vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600133 break;
134 case SPRN_IVOR35:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100135 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600136 break;
137
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600138 default:
139 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
140 }
141
142 return emulated;
143}
144
145int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
146{
147 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
148 int emulated = EMULATE_DONE;
Scott Woodb5904972011-11-08 18:23:30 -0600149 unsigned long val;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600150
151 switch (sprn) {
152 case SPRN_PID:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100153 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600154 case SPRN_PID1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100155 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600156 case SPRN_PID2:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100157 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600158 case SPRN_MAS0:
Scott Woodb5904972011-11-08 18:23:30 -0600159 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas0); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600160 case SPRN_MAS1:
Scott Woodb5904972011-11-08 18:23:30 -0600161 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas1); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600162 case SPRN_MAS2:
Scott Woodb5904972011-11-08 18:23:30 -0600163 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas2); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600164 case SPRN_MAS3:
Scott Woodb5904972011-11-08 18:23:30 -0600165 val = (u32)vcpu->arch.shared->mas7_3;
166 kvmppc_set_gpr(vcpu, rt, val);
167 break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600168 case SPRN_MAS4:
Scott Woodb5904972011-11-08 18:23:30 -0600169 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas4); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600170 case SPRN_MAS6:
Scott Woodb5904972011-11-08 18:23:30 -0600171 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas6); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600172 case SPRN_MAS7:
Scott Woodb5904972011-11-08 18:23:30 -0600173 val = vcpu->arch.shared->mas7_3 >> 32;
174 kvmppc_set_gpr(vcpu, rt, val);
175 break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600176 case SPRN_TLB0CFG:
Scott Wood8fdd21a22011-12-20 15:34:34 +0000177 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tlbcfg[0]); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600178 case SPRN_TLB1CFG:
Scott Wood8fdd21a22011-12-20 15:34:34 +0000179 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tlbcfg[1]); break;
Liu Yud86be072010-01-22 18:50:29 +0800180 case SPRN_L1CSR0:
181 kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr0); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600182 case SPRN_L1CSR1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100183 kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600184 case SPRN_HID0:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100185 kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600186 case SPRN_HID1:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100187 kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break;
Scott Wood90d34b02011-03-29 16:49:10 -0500188 case SPRN_SVR:
189 kvmppc_set_gpr(vcpu, rt, vcpu_e500->svr); break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600190
Liu Yub0a18352009-02-17 16:52:08 +0800191 case SPRN_MMUCSR0:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100192 kvmppc_set_gpr(vcpu, rt, 0); break;
Liu Yub0a18352009-02-17 16:52:08 +0800193
Liu Yu06579dd2009-06-05 14:54:31 +0800194 case SPRN_MMUCFG:
Scott Wood8fdd21a22011-12-20 15:34:34 +0000195 kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucfg); break;
Liu Yu06579dd2009-06-05 14:54:31 +0800196
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600197 /* extra exceptions */
198 case SPRN_IVOR32:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100199 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]);
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600200 break;
201 case SPRN_IVOR33:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100202 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]);
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600203 break;
204 case SPRN_IVOR34:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100205 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]);
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600206 break;
207 case SPRN_IVOR35:
Alexander Graf8e5b26b2010-01-08 02:58:01 +0100208 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]);
Hollis Blanchardbb3a8a12009-01-03 16:23:13 -0600209 break;
Hollis Blanchardbc8080c2009-01-03 16:23:10 -0600210 default:
211 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
212 }
213
214 return emulated;
215}
216