Commit | Line | Data |
---|---|---|
d0c7dc03 HB |
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 | |
dfd4d47e | 16 | * Copyright 2011 Freescale Semiconductor, Inc. |
d0c7dc03 HB |
17 | * |
18 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | |
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 | |
0c1fc3c3 | 27 | #define OP_19_XOP_RFCI 51 |
c8ca97ca | 28 | #define OP_19_XOP_RFDI 39 |
d0c7dc03 HB |
29 | |
30 | #define OP_31_XOP_MFMSR 83 | |
31 | #define OP_31_XOP_WRTEE 131 | |
32 | #define OP_31_XOP_MTMSR 146 | |
33 | #define OP_31_XOP_WRTEEI 163 | |
34 | ||
35 | static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu) | |
36 | { | |
173c520a | 37 | vcpu->arch.regs.nip = vcpu->arch.shared->srr0; |
de7906c3 | 38 | kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1); |
d0c7dc03 HB |
39 | } |
40 | ||
c8ca97ca BB |
41 | static void kvmppc_emul_rfdi(struct kvm_vcpu *vcpu) |
42 | { | |
173c520a | 43 | vcpu->arch.regs.nip = vcpu->arch.dsrr0; |
c8ca97ca BB |
44 | kvmppc_set_msr(vcpu, vcpu->arch.dsrr1); |
45 | } | |
46 | ||
0c1fc3c3 BB |
47 | static void kvmppc_emul_rfci(struct kvm_vcpu *vcpu) |
48 | { | |
173c520a | 49 | vcpu->arch.regs.nip = vcpu->arch.csrr0; |
0c1fc3c3 BB |
50 | kvmppc_set_msr(vcpu, vcpu->arch.csrr1); |
51 | } | |
52 | ||
d0c7dc03 HB |
53 | int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, |
54 | unsigned int inst, int *advance) | |
55 | { | |
56 | int emulated = EMULATE_DONE; | |
c46dc9a8 AG |
57 | int rs = get_rs(inst); |
58 | int rt = get_rt(inst); | |
d0c7dc03 HB |
59 | |
60 | switch (get_op(inst)) { | |
61 | case 19: | |
62 | switch (get_xop(inst)) { | |
63 | case OP_19_XOP_RFI: | |
64 | kvmppc_emul_rfi(vcpu); | |
65 | kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS); | |
66 | *advance = 0; | |
67 | break; | |
68 | ||
0c1fc3c3 BB |
69 | case OP_19_XOP_RFCI: |
70 | kvmppc_emul_rfci(vcpu); | |
71 | kvmppc_set_exit_type(vcpu, EMULATED_RFCI_EXITS); | |
72 | *advance = 0; | |
73 | break; | |
74 | ||
c8ca97ca BB |
75 | case OP_19_XOP_RFDI: |
76 | kvmppc_emul_rfdi(vcpu); | |
77 | kvmppc_set_exit_type(vcpu, EMULATED_RFDI_EXITS); | |
78 | *advance = 0; | |
79 | break; | |
80 | ||
d0c7dc03 HB |
81 | default: |
82 | emulated = EMULATE_FAIL; | |
83 | break; | |
84 | } | |
85 | break; | |
86 | ||
87 | case 31: | |
88 | switch (get_xop(inst)) { | |
89 | ||
90 | case OP_31_XOP_MFMSR: | |
666e7252 | 91 | kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr); |
d0c7dc03 HB |
92 | kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS); |
93 | break; | |
94 | ||
95 | case OP_31_XOP_MTMSR: | |
d0c7dc03 | 96 | kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS); |
8e5b26b5 | 97 | kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs)); |
d0c7dc03 HB |
98 | break; |
99 | ||
100 | case OP_31_XOP_WRTEE: | |
666e7252 | 101 | vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE) |
8e5b26b5 | 102 | | (kvmppc_get_gpr(vcpu, rs) & MSR_EE); |
d0c7dc03 HB |
103 | kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS); |
104 | break; | |
105 | ||
106 | case OP_31_XOP_WRTEEI: | |
666e7252 | 107 | vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE) |
d0c7dc03 HB |
108 | | (inst & MSR_EE); |
109 | kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS); | |
110 | break; | |
111 | ||
112 | default: | |
113 | emulated = EMULATE_FAIL; | |
114 | } | |
115 | ||
116 | break; | |
117 | ||
118 | default: | |
119 | emulated = EMULATE_FAIL; | |
120 | } | |
121 | ||
122 | return emulated; | |
123 | } | |
124 | ||
d30f6e48 SW |
125 | /* |
126 | * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode). | |
127 | * Their backing store is in real registers, and these functions | |
128 | * will return the wrong result if called for them in another context | |
129 | * (such as debugging). | |
130 | */ | |
54771e62 | 131 | int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) |
d0c7dc03 HB |
132 | { |
133 | int emulated = EMULATE_DONE; | |
2f699a59 | 134 | bool debug_inst = false; |
d0c7dc03 HB |
135 | |
136 | switch (sprn) { | |
137 | case SPRN_DEAR: | |
54771e62 AG |
138 | vcpu->arch.shared->dar = spr_val; |
139 | break; | |
d0c7dc03 | 140 | case SPRN_ESR: |
54771e62 AG |
141 | vcpu->arch.shared->esr = spr_val; |
142 | break; | |
0c1fc3c3 BB |
143 | case SPRN_CSRR0: |
144 | vcpu->arch.csrr0 = spr_val; | |
145 | break; | |
146 | case SPRN_CSRR1: | |
147 | vcpu->arch.csrr1 = spr_val; | |
148 | break; | |
2f699a59 BB |
149 | case SPRN_DSRR0: |
150 | vcpu->arch.dsrr0 = spr_val; | |
151 | break; | |
152 | case SPRN_DSRR1: | |
153 | vcpu->arch.dsrr1 = spr_val; | |
154 | break; | |
155 | case SPRN_IAC1: | |
156 | /* | |
157 | * If userspace is debugging guest then guest | |
158 | * can not access debug registers. | |
159 | */ | |
160 | if (vcpu->guest_debug) | |
161 | break; | |
162 | ||
163 | debug_inst = true; | |
164 | vcpu->arch.dbg_reg.iac1 = spr_val; | |
165 | break; | |
166 | case SPRN_IAC2: | |
167 | /* | |
168 | * If userspace is debugging guest then guest | |
169 | * can not access debug registers. | |
170 | */ | |
171 | if (vcpu->guest_debug) | |
172 | break; | |
173 | ||
174 | debug_inst = true; | |
175 | vcpu->arch.dbg_reg.iac2 = spr_val; | |
176 | break; | |
177 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | |
178 | case SPRN_IAC3: | |
179 | /* | |
180 | * If userspace is debugging guest then guest | |
181 | * can not access debug registers. | |
182 | */ | |
183 | if (vcpu->guest_debug) | |
184 | break; | |
185 | ||
186 | debug_inst = true; | |
187 | vcpu->arch.dbg_reg.iac3 = spr_val; | |
188 | break; | |
189 | case SPRN_IAC4: | |
190 | /* | |
191 | * If userspace is debugging guest then guest | |
192 | * can not access debug registers. | |
193 | */ | |
194 | if (vcpu->guest_debug) | |
195 | break; | |
196 | ||
197 | debug_inst = true; | |
198 | vcpu->arch.dbg_reg.iac4 = spr_val; | |
199 | break; | |
200 | #endif | |
201 | case SPRN_DAC1: | |
202 | /* | |
203 | * If userspace is debugging guest then guest | |
204 | * can not access debug registers. | |
205 | */ | |
206 | if (vcpu->guest_debug) | |
207 | break; | |
208 | ||
209 | debug_inst = true; | |
210 | vcpu->arch.dbg_reg.dac1 = spr_val; | |
211 | break; | |
212 | case SPRN_DAC2: | |
213 | /* | |
214 | * If userspace is debugging guest then guest | |
215 | * can not access debug registers. | |
216 | */ | |
217 | if (vcpu->guest_debug) | |
218 | break; | |
219 | ||
220 | debug_inst = true; | |
221 | vcpu->arch.dbg_reg.dac2 = spr_val; | |
222 | break; | |
d0c7dc03 | 223 | case SPRN_DBCR0: |
2f699a59 BB |
224 | /* |
225 | * If userspace is debugging guest then guest | |
226 | * can not access debug registers. | |
227 | */ | |
228 | if (vcpu->guest_debug) | |
229 | break; | |
230 | ||
231 | debug_inst = true; | |
232 | spr_val &= (DBCR0_IDM | DBCR0_IC | DBCR0_BT | DBCR0_TIE | | |
233 | DBCR0_IAC1 | DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | | |
234 | DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W); | |
235 | ||
6df8d3fc | 236 | vcpu->arch.dbg_reg.dbcr0 = spr_val; |
54771e62 | 237 | break; |
d0c7dc03 | 238 | case SPRN_DBCR1: |
2f699a59 BB |
239 | /* |
240 | * If userspace is debugging guest then guest | |
241 | * can not access debug registers. | |
242 | */ | |
243 | if (vcpu->guest_debug) | |
244 | break; | |
245 | ||
246 | debug_inst = true; | |
6df8d3fc | 247 | vcpu->arch.dbg_reg.dbcr1 = spr_val; |
54771e62 | 248 | break; |
2f699a59 BB |
249 | case SPRN_DBCR2: |
250 | /* | |
251 | * If userspace is debugging guest then guest | |
252 | * can not access debug registers. | |
253 | */ | |
254 | if (vcpu->guest_debug) | |
255 | break; | |
256 | ||
257 | debug_inst = true; | |
258 | vcpu->arch.dbg_reg.dbcr2 = spr_val; | |
259 | break; | |
f7b200af | 260 | case SPRN_DBSR: |
2f699a59 BB |
261 | /* |
262 | * If userspace is debugging guest then guest | |
263 | * can not access debug registers. | |
264 | */ | |
265 | if (vcpu->guest_debug) | |
266 | break; | |
267 | ||
54771e62 | 268 | vcpu->arch.dbsr &= ~spr_val; |
2f699a59 BB |
269 | if (!(vcpu->arch.dbsr & ~DBSR_IDE)) |
270 | kvmppc_core_dequeue_debug(vcpu); | |
54771e62 | 271 | break; |
d0c7dc03 | 272 | case SPRN_TSR: |
dfd4d47e SW |
273 | kvmppc_clr_tsr_bits(vcpu, spr_val); |
274 | break; | |
d0c7dc03 | 275 | case SPRN_TCR: |
f61c94bb BB |
276 | /* |
277 | * WRC is a 2-bit field that is supposed to preserve its | |
278 | * value once written to non-zero. | |
279 | */ | |
280 | if (vcpu->arch.tcr & TCR_WRC_MASK) { | |
281 | spr_val &= ~TCR_WRC_MASK; | |
282 | spr_val |= vcpu->arch.tcr & TCR_WRC_MASK; | |
283 | } | |
dfd4d47e | 284 | kvmppc_set_tcr(vcpu, spr_val); |
d0c7dc03 HB |
285 | break; |
286 | ||
21bd000a BB |
287 | case SPRN_DECAR: |
288 | vcpu->arch.decar = spr_val; | |
289 | break; | |
d30f6e48 SW |
290 | /* |
291 | * Note: SPRG4-7 are user-readable. | |
292 | * These values are loaded into the real SPRGs when resuming the | |
293 | * guest (PR-mode only). | |
294 | */ | |
d0c7dc03 | 295 | case SPRN_SPRG4: |
c1b8a01b | 296 | kvmppc_set_sprg4(vcpu, spr_val); |
54771e62 | 297 | break; |
d0c7dc03 | 298 | case SPRN_SPRG5: |
c1b8a01b | 299 | kvmppc_set_sprg5(vcpu, spr_val); |
54771e62 | 300 | break; |
d0c7dc03 | 301 | case SPRN_SPRG6: |
c1b8a01b | 302 | kvmppc_set_sprg6(vcpu, spr_val); |
54771e62 | 303 | break; |
d0c7dc03 | 304 | case SPRN_SPRG7: |
c1b8a01b | 305 | kvmppc_set_sprg7(vcpu, spr_val); |
54771e62 | 306 | break; |
d0c7dc03 HB |
307 | |
308 | case SPRN_IVPR: | |
8e5b26b5 | 309 | vcpu->arch.ivpr = spr_val; |
d30f6e48 SW |
310 | #ifdef CONFIG_KVM_BOOKE_HV |
311 | mtspr(SPRN_GIVPR, spr_val); | |
312 | #endif | |
d0c7dc03 HB |
313 | break; |
314 | case SPRN_IVOR0: | |
8e5b26b5 | 315 | vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val; |
d0c7dc03 HB |
316 | break; |
317 | case SPRN_IVOR1: | |
8e5b26b5 | 318 | vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val; |
d0c7dc03 HB |
319 | break; |
320 | case SPRN_IVOR2: | |
8e5b26b5 | 321 | vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; |
d30f6e48 SW |
322 | #ifdef CONFIG_KVM_BOOKE_HV |
323 | mtspr(SPRN_GIVOR2, spr_val); | |
324 | #endif | |
d0c7dc03 HB |
325 | break; |
326 | case SPRN_IVOR3: | |
8e5b26b5 | 327 | vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val; |
d0c7dc03 HB |
328 | break; |
329 | case SPRN_IVOR4: | |
8e5b26b5 | 330 | vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val; |
d0c7dc03 HB |
331 | break; |
332 | case SPRN_IVOR5: | |
8e5b26b5 | 333 | vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val; |
d0c7dc03 HB |
334 | break; |
335 | case SPRN_IVOR6: | |
8e5b26b5 | 336 | vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val; |
d0c7dc03 HB |
337 | break; |
338 | case SPRN_IVOR7: | |
8e5b26b5 | 339 | vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val; |
d0c7dc03 HB |
340 | break; |
341 | case SPRN_IVOR8: | |
8e5b26b5 | 342 | vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; |
d30f6e48 SW |
343 | #ifdef CONFIG_KVM_BOOKE_HV |
344 | mtspr(SPRN_GIVOR8, spr_val); | |
345 | #endif | |
d0c7dc03 HB |
346 | break; |
347 | case SPRN_IVOR9: | |
8e5b26b5 | 348 | vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; |
d0c7dc03 HB |
349 | break; |
350 | case SPRN_IVOR10: | |
8e5b26b5 | 351 | vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val; |
d0c7dc03 HB |
352 | break; |
353 | case SPRN_IVOR11: | |
8e5b26b5 | 354 | vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val; |
d0c7dc03 HB |
355 | break; |
356 | case SPRN_IVOR12: | |
8e5b26b5 | 357 | vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val; |
d0c7dc03 HB |
358 | break; |
359 | case SPRN_IVOR13: | |
8e5b26b5 | 360 | vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val; |
d0c7dc03 HB |
361 | break; |
362 | case SPRN_IVOR14: | |
8e5b26b5 | 363 | vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val; |
d0c7dc03 HB |
364 | break; |
365 | case SPRN_IVOR15: | |
8e5b26b5 | 366 | vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val; |
d0c7dc03 | 367 | break; |
50c871ed AG |
368 | case SPRN_MCSR: |
369 | vcpu->arch.mcsr &= ~spr_val; | |
370 | break; | |
38f98824 MC |
371 | #if defined(CONFIG_64BIT) |
372 | case SPRN_EPCR: | |
373 | kvmppc_set_epcr(vcpu, spr_val); | |
374 | #ifdef CONFIG_KVM_BOOKE_HV | |
375 | mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr); | |
376 | #endif | |
377 | break; | |
378 | #endif | |
d0c7dc03 HB |
379 | default: |
380 | emulated = EMULATE_FAIL; | |
381 | } | |
382 | ||
2f699a59 BB |
383 | if (debug_inst) { |
384 | current->thread.debug = vcpu->arch.dbg_reg; | |
385 | switch_booke_debug_regs(&vcpu->arch.dbg_reg); | |
386 | } | |
d0c7dc03 HB |
387 | return emulated; |
388 | } | |
389 | ||
54771e62 | 390 | int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) |
d0c7dc03 HB |
391 | { |
392 | int emulated = EMULATE_DONE; | |
393 | ||
394 | switch (sprn) { | |
395 | case SPRN_IVPR: | |
54771e62 AG |
396 | *spr_val = vcpu->arch.ivpr; |
397 | break; | |
d0c7dc03 | 398 | case SPRN_DEAR: |
54771e62 AG |
399 | *spr_val = vcpu->arch.shared->dar; |
400 | break; | |
d0c7dc03 | 401 | case SPRN_ESR: |
54771e62 AG |
402 | *spr_val = vcpu->arch.shared->esr; |
403 | break; | |
37ecb257 AG |
404 | case SPRN_EPR: |
405 | *spr_val = vcpu->arch.epr; | |
406 | break; | |
0c1fc3c3 BB |
407 | case SPRN_CSRR0: |
408 | *spr_val = vcpu->arch.csrr0; | |
409 | break; | |
410 | case SPRN_CSRR1: | |
411 | *spr_val = vcpu->arch.csrr1; | |
412 | break; | |
2f699a59 BB |
413 | case SPRN_DSRR0: |
414 | *spr_val = vcpu->arch.dsrr0; | |
415 | break; | |
416 | case SPRN_DSRR1: | |
417 | *spr_val = vcpu->arch.dsrr1; | |
418 | break; | |
419 | case SPRN_IAC1: | |
420 | *spr_val = vcpu->arch.dbg_reg.iac1; | |
421 | break; | |
422 | case SPRN_IAC2: | |
423 | *spr_val = vcpu->arch.dbg_reg.iac2; | |
424 | break; | |
425 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | |
426 | case SPRN_IAC3: | |
427 | *spr_val = vcpu->arch.dbg_reg.iac3; | |
428 | break; | |
429 | case SPRN_IAC4: | |
430 | *spr_val = vcpu->arch.dbg_reg.iac4; | |
431 | break; | |
432 | #endif | |
433 | case SPRN_DAC1: | |
434 | *spr_val = vcpu->arch.dbg_reg.dac1; | |
435 | break; | |
436 | case SPRN_DAC2: | |
437 | *spr_val = vcpu->arch.dbg_reg.dac2; | |
438 | break; | |
d0c7dc03 | 439 | case SPRN_DBCR0: |
6df8d3fc | 440 | *spr_val = vcpu->arch.dbg_reg.dbcr0; |
348ba710 BB |
441 | if (vcpu->guest_debug) |
442 | *spr_val = *spr_val | DBCR0_EDM; | |
54771e62 | 443 | break; |
d0c7dc03 | 444 | case SPRN_DBCR1: |
6df8d3fc | 445 | *spr_val = vcpu->arch.dbg_reg.dbcr1; |
54771e62 | 446 | break; |
2f699a59 BB |
447 | case SPRN_DBCR2: |
448 | *spr_val = vcpu->arch.dbg_reg.dbcr2; | |
449 | break; | |
f7b200af | 450 | case SPRN_DBSR: |
54771e62 AG |
451 | *spr_val = vcpu->arch.dbsr; |
452 | break; | |
dfd4d47e | 453 | case SPRN_TSR: |
54771e62 AG |
454 | *spr_val = vcpu->arch.tsr; |
455 | break; | |
dfd4d47e | 456 | case SPRN_TCR: |
54771e62 AG |
457 | *spr_val = vcpu->arch.tcr; |
458 | break; | |
d0c7dc03 HB |
459 | |
460 | case SPRN_IVOR0: | |
54771e62 | 461 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]; |
d0c7dc03 HB |
462 | break; |
463 | case SPRN_IVOR1: | |
54771e62 | 464 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]; |
d0c7dc03 HB |
465 | break; |
466 | case SPRN_IVOR2: | |
54771e62 | 467 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]; |
d0c7dc03 HB |
468 | break; |
469 | case SPRN_IVOR3: | |
54771e62 | 470 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]; |
d0c7dc03 HB |
471 | break; |
472 | case SPRN_IVOR4: | |
54771e62 | 473 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]; |
d0c7dc03 HB |
474 | break; |
475 | case SPRN_IVOR5: | |
54771e62 | 476 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]; |
d0c7dc03 HB |
477 | break; |
478 | case SPRN_IVOR6: | |
54771e62 | 479 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]; |
d0c7dc03 HB |
480 | break; |
481 | case SPRN_IVOR7: | |
54771e62 | 482 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]; |
d0c7dc03 HB |
483 | break; |
484 | case SPRN_IVOR8: | |
54771e62 | 485 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]; |
d0c7dc03 HB |
486 | break; |
487 | case SPRN_IVOR9: | |
54771e62 | 488 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]; |
d0c7dc03 HB |
489 | break; |
490 | case SPRN_IVOR10: | |
54771e62 | 491 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]; |
d0c7dc03 HB |
492 | break; |
493 | case SPRN_IVOR11: | |
54771e62 | 494 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]; |
d0c7dc03 HB |
495 | break; |
496 | case SPRN_IVOR12: | |
54771e62 | 497 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]; |
d0c7dc03 HB |
498 | break; |
499 | case SPRN_IVOR13: | |
54771e62 | 500 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]; |
d0c7dc03 HB |
501 | break; |
502 | case SPRN_IVOR14: | |
54771e62 | 503 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]; |
d0c7dc03 HB |
504 | break; |
505 | case SPRN_IVOR15: | |
54771e62 | 506 | *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]; |
d0c7dc03 | 507 | break; |
50c871ed AG |
508 | case SPRN_MCSR: |
509 | *spr_val = vcpu->arch.mcsr; | |
510 | break; | |
38f98824 MC |
511 | #if defined(CONFIG_64BIT) |
512 | case SPRN_EPCR: | |
513 | *spr_val = vcpu->arch.epcr; | |
514 | break; | |
515 | #endif | |
d0c7dc03 HB |
516 | |
517 | default: | |
518 | emulated = EMULATE_FAIL; | |
519 | } | |
520 | ||
521 | return emulated; | |
522 | } |