Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
booke_emulate.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License, version 2, as
4  * published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14  *
15  * Copyright IBM Corp. 2008
16  * Copyright 2011 Freescale Semiconductor, Inc.
17  *
18  * Authors: Hollis Blanchard <[email protected]>
19  */
20 
21 #include <linux/kvm_host.h>
22 #include <asm/disassemble.h>
23 
24 #include "booke.h"
25 
26 #define OP_19_XOP_RFI 50
27 #define OP_19_XOP_RFCI 51
28 
29 #define OP_31_XOP_MFMSR 83
30 #define OP_31_XOP_WRTEE 131
31 #define OP_31_XOP_MTMSR 146
32 #define OP_31_XOP_WRTEEI 163
33 
34 static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
35 {
36  vcpu->arch.pc = vcpu->arch.shared->srr0;
37  kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
38 }
39 
40 static void kvmppc_emul_rfci(struct kvm_vcpu *vcpu)
41 {
42  vcpu->arch.pc = vcpu->arch.csrr0;
43  kvmppc_set_msr(vcpu, vcpu->arch.csrr1);
44 }
45 
46 int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
47  unsigned int inst, int *advance)
48 {
49  int emulated = EMULATE_DONE;
50  int rs = get_rs(inst);
51  int rt = get_rt(inst);
52 
53  switch (get_op(inst)) {
54  case 19:
55  switch (get_xop(inst)) {
56  case OP_19_XOP_RFI:
57  kvmppc_emul_rfi(vcpu);
58  kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
59  *advance = 0;
60  break;
61 
62  case OP_19_XOP_RFCI:
63  kvmppc_emul_rfci(vcpu);
64  kvmppc_set_exit_type(vcpu, EMULATED_RFCI_EXITS);
65  *advance = 0;
66  break;
67 
68  default:
69  emulated = EMULATE_FAIL;
70  break;
71  }
72  break;
73 
74  case 31:
75  switch (get_xop(inst)) {
76 
77  case OP_31_XOP_MFMSR:
78  kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
79  kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
80  break;
81 
82  case OP_31_XOP_MTMSR:
83  kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
84  kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
85  break;
86 
87  case OP_31_XOP_WRTEE:
88  vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
89  | (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
90  kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
91  break;
92 
93  case OP_31_XOP_WRTEEI:
94  vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
95  | (inst & MSR_EE);
96  kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
97  break;
98 
99  default:
100  emulated = EMULATE_FAIL;
101  }
102 
103  break;
104 
105  default:
106  emulated = EMULATE_FAIL;
107  }
108 
109  return emulated;
110 }
111 
112 /*
113  * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode).
114  * Their backing store is in real registers, and these functions
115  * will return the wrong result if called for them in another context
116  * (such as debugging).
117  */
118 int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
119 {
120  int emulated = EMULATE_DONE;
121 
122  switch (sprn) {
123  case SPRN_DEAR:
124  vcpu->arch.shared->dar = spr_val;
125  break;
126  case SPRN_ESR:
127  vcpu->arch.shared->esr = spr_val;
128  break;
129  case SPRN_CSRR0:
130  vcpu->arch.csrr0 = spr_val;
131  break;
132  case SPRN_CSRR1:
133  vcpu->arch.csrr1 = spr_val;
134  break;
135  case SPRN_DBCR0:
136  vcpu->arch.dbcr0 = spr_val;
137  break;
138  case SPRN_DBCR1:
139  vcpu->arch.dbcr1 = spr_val;
140  break;
141  case SPRN_DBSR:
142  vcpu->arch.dbsr &= ~spr_val;
143  break;
144  case SPRN_TSR:
145  kvmppc_clr_tsr_bits(vcpu, spr_val);
146  break;
147  case SPRN_TCR:
148  kvmppc_set_tcr(vcpu, spr_val);
149  break;
150 
151  case SPRN_DECAR:
152  vcpu->arch.decar = spr_val;
153  break;
154  /*
155  * Note: SPRG4-7 are user-readable.
156  * These values are loaded into the real SPRGs when resuming the
157  * guest (PR-mode only).
158  */
159  case SPRN_SPRG4:
160  vcpu->arch.shared->sprg4 = spr_val;
161  break;
162  case SPRN_SPRG5:
163  vcpu->arch.shared->sprg5 = spr_val;
164  break;
165  case SPRN_SPRG6:
166  vcpu->arch.shared->sprg6 = spr_val;
167  break;
168  case SPRN_SPRG7:
169  vcpu->arch.shared->sprg7 = spr_val;
170  break;
171 
172  case SPRN_IVPR:
173  vcpu->arch.ivpr = spr_val;
174 #ifdef CONFIG_KVM_BOOKE_HV
175  mtspr(SPRN_GIVPR, spr_val);
176 #endif
177  break;
178  case SPRN_IVOR0:
179  vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
180  break;
181  case SPRN_IVOR1:
182  vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
183  break;
184  case SPRN_IVOR2:
185  vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
186 #ifdef CONFIG_KVM_BOOKE_HV
187  mtspr(SPRN_GIVOR2, spr_val);
188 #endif
189  break;
190  case SPRN_IVOR3:
191  vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
192  break;
193  case SPRN_IVOR4:
194  vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val;
195  break;
196  case SPRN_IVOR5:
197  vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val;
198  break;
199  case SPRN_IVOR6:
200  vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val;
201  break;
202  case SPRN_IVOR7:
203  vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
204  break;
205  case SPRN_IVOR8:
206  vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
207 #ifdef CONFIG_KVM_BOOKE_HV
208  mtspr(SPRN_GIVOR8, spr_val);
209 #endif
210  break;
211  case SPRN_IVOR9:
212  vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
213  break;
214  case SPRN_IVOR10:
215  vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val;
216  break;
217  case SPRN_IVOR11:
218  vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val;
219  break;
220  case SPRN_IVOR12:
221  vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val;
222  break;
223  case SPRN_IVOR13:
224  vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val;
225  break;
226  case SPRN_IVOR14:
227  vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val;
228  break;
229  case SPRN_IVOR15:
230  vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val;
231  break;
232 
233  default:
234  emulated = EMULATE_FAIL;
235  }
236 
237  return emulated;
238 }
239 
240 int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
241 {
242  int emulated = EMULATE_DONE;
243 
244  switch (sprn) {
245  case SPRN_IVPR:
246  *spr_val = vcpu->arch.ivpr;
247  break;
248  case SPRN_DEAR:
249  *spr_val = vcpu->arch.shared->dar;
250  break;
251  case SPRN_ESR:
252  *spr_val = vcpu->arch.shared->esr;
253  break;
254  case SPRN_CSRR0:
255  *spr_val = vcpu->arch.csrr0;
256  break;
257  case SPRN_CSRR1:
258  *spr_val = vcpu->arch.csrr1;
259  break;
260  case SPRN_DBCR0:
261  *spr_val = vcpu->arch.dbcr0;
262  break;
263  case SPRN_DBCR1:
264  *spr_val = vcpu->arch.dbcr1;
265  break;
266  case SPRN_DBSR:
267  *spr_val = vcpu->arch.dbsr;
268  break;
269  case SPRN_TSR:
270  *spr_val = vcpu->arch.tsr;
271  break;
272  case SPRN_TCR:
273  *spr_val = vcpu->arch.tcr;
274  break;
275 
276  case SPRN_IVOR0:
277  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
278  break;
279  case SPRN_IVOR1:
280  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
281  break;
282  case SPRN_IVOR2:
283  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
284  break;
285  case SPRN_IVOR3:
286  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
287  break;
288  case SPRN_IVOR4:
289  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
290  break;
291  case SPRN_IVOR5:
292  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
293  break;
294  case SPRN_IVOR6:
295  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
296  break;
297  case SPRN_IVOR7:
298  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
299  break;
300  case SPRN_IVOR8:
301  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
302  break;
303  case SPRN_IVOR9:
304  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
305  break;
306  case SPRN_IVOR10:
307  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
308  break;
309  case SPRN_IVOR11:
310  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
311  break;
312  case SPRN_IVOR12:
313  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
314  break;
315  case SPRN_IVOR13:
316  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
317  break;
318  case SPRN_IVOR14:
319  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
320  break;
321  case SPRN_IVOR15:
322  *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
323  break;
324 
325  default:
326  emulated = EMULATE_FAIL;
327  }
328 
329  return emulated;
330 }