emulate.c revision 689fd14ae9b2af5c6862ddc11d4791ec9a938cb3
1bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/*
2bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * This program is free software; you can redistribute it and/or modify
3bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * it under the terms of the GNU General Public License, version 2, as
4bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * published by the Free Software Foundation.
5bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
6bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * This program is distributed in the hope that it will be useful,
7bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * but WITHOUT ANY WARRANTY; without even the implied warranty of
8bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * GNU General Public License for more details.
10bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
11bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * You should have received a copy of the GNU General Public License
12bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * along with this program; if not, write to the Free Software
13bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
15bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Copyright IBM Corp. 2007
16bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
17bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
19bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
20bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/jiffies.h>
21544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf#include <linux/hrtimer.h>
22bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/types.h>
23bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/string.h>
24bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/kvm_host.h>
25bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard#include <asm/reg.h>
27bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/time.h>
28bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/byteorder.h>
29bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/kvm_ppc.h>
30c381a04313e7c0fb04246b1ff711e0b5726de6c0Hollis Blanchard#include <asm/disassemble.h>
3173e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard#include "timing.h"
3246f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti#include "trace.h"
33bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
34cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_TRAP 3
35513579e3a391a3874c478a8493080822069976e8Alexander Graf#define OP_TRAP_64 2
36cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
37cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWZX      23
38cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LBZX      87
39cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWX      151
40cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBX      215
411c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf#define OP_31_XOP_LBZUX     119
42cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBUX     247
43cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZX      279
44cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZUX     311
45cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MFSPR     339
461c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf#define OP_31_XOP_LHAX      343
47cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHX      407
48cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHUX     439
49cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MTSPR     467
50cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_DCBI      470
51cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWBRX     534
52cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_TLBSYNC   566
53cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWBRX    662
54cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHBRX     790
55cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHBRX    918
56cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
57cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZ  32
58cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZU 33
59cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZ  34
60cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZU 35
61cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STW  36
62cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STWU 37
63cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STB  38
64cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STBU 39
65cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZ  40
66cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZU 41
673587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf#define OP_LHA  42
683587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf#define OP_LHAU 43
69cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STH  44
70cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STHU 45
71cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
7200c3a37ca332f54f2187720e51f7c0e18e91d7c9Alexander Graf#ifdef CONFIG_PPC_BOOK3S
73513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
74513579e3a391a3874c478a8493080822069976e8Alexander Graf{
75513579e3a391a3874c478a8493080822069976e8Alexander Graf	return 1;
76513579e3a391a3874c478a8493080822069976e8Alexander Graf}
77513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
78513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu)
79513579e3a391a3874c478a8493080822069976e8Alexander Graf{
80513579e3a391a3874c478a8493080822069976e8Alexander Graf	return vcpu->arch.tcr & TCR_DIE;
81513579e3a391a3874c478a8493080822069976e8Alexander Graf}
82513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
83513579e3a391a3874c478a8493080822069976e8Alexander Graf
8475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchardvoid kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
85bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
86544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	unsigned long dec_nsec;
879a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf
88544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
8900c3a37ca332f54f2187720e51f7c0e18e91d7c9Alexander Graf#ifdef CONFIG_PPC_BOOK3S
907706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	/* mtdec lowers the interrupt line when positive. */
917706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	kvmppc_core_dequeue_dec(vcpu);
927706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf
93513579e3a391a3874c478a8493080822069976e8Alexander Graf	/* POWER4+ triggers a dec interrupt if the value is < 0 */
94513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (vcpu->arch.dec & 0x80000000) {
95544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
96513579e3a391a3874c478a8493080822069976e8Alexander Graf		kvmppc_core_queue_dec(vcpu);
97513579e3a391a3874c478a8493080822069976e8Alexander Graf		return;
98513579e3a391a3874c478a8493080822069976e8Alexander Graf	}
99513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
100513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (kvmppc_dec_enabled(vcpu)) {
101bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		/* The decrementer ticks at the same rate as the timebase, so
102bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * that's how we convert the guest DEC value to the number of
103bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		 * host ticks. */
104bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
105544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
106544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec = vcpu->arch.dec;
107544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec *= 1000;
108544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		dec_nsec /= tb_ticks_per_usec;
109544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec),
110544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf			      HRTIMER_MODE_REL);
111513579e3a391a3874c478a8493080822069976e8Alexander Graf		vcpu->arch.dec_jiffies = get_tb();
112bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	} else {
113544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
114bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
115bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
116bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
117bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/* XXX to do:
118bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhax
119bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhaux
120bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswx
121bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswi
122bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswx
123bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswi
124bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lha
125bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhau
126bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lmw
127bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stmw
128bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
129bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * XXX is_bigendian should depend on MMU mapping or MSR[LE]
130bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
13175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard/* XXX Should probably auto-generate instruction decoding for a particular core
13275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard * from opcode tables in the future. */
133bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchardint kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
134bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
135c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	u32 inst = kvmppc_get_last_inst(vcpu);
136bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 ea;
137bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int ra;
138bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rb;
139bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rs;
140bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rt;
141bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int sprn;
142bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	enum emulation_result emulated = EMULATE_DONE;
143bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int advance = 1;
144bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
14573e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	/* this default type might be overwritten by subcategories */
14673e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
14773e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard
148689fd14ae9b2af5c6862ddc11d4791ec9a938cb3Joe Perches	pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
149513579e3a391a3874c478a8493080822069976e8Alexander Graf
150bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	switch (get_op(inst)) {
151cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_TRAP:
15200c3a37ca332f54f2187720e51f7c0e18e91d7c9Alexander Graf#ifdef CONFIG_PPC_BOOK3S
153513579e3a391a3874c478a8493080822069976e8Alexander Graf	case OP_TRAP_64:
154daf5e27109c8c16c987e955cc6abbbc0af050eddLiu Yu		kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
155513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
156daf5e27109c8c16c987e955cc6abbbc0af050eddLiu Yu		kvmppc_core_queue_program(vcpu, vcpu->arch.esr | ESR_PTR);
157513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
158bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		advance = 0;
159bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
160bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
161bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	case 31:
162bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		switch (get_xop(inst)) {
163bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
164cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWZX:
165ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rt = get_rt(inst);
166ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
167ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
168ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
169cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LBZX:
170bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
171bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
172bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
173bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
1741c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf		case OP_31_XOP_LBZUX:
1751c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rt = get_rt(inst);
1761c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			ra = get_ra(inst);
1771c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rb = get_rb(inst);
1781c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
1791c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
1801c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			if (ra)
1811c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
1821c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
1831c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
1841c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
1851c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			break;
1861c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
187cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWX:
188ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rs = get_rs(inst);
189ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1908e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
191ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			                               4, 1);
192ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
193ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
194cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBX:
195bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
196bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1978e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
198bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
199bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
200bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
201cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBUX:
202bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
203bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
204bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
205bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2068e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
207bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2088e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
209bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
210bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2118e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
212bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
2138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, rs, ea);
214bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
215bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2161c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf		case OP_31_XOP_LHAX:
2171c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rt = get_rt(inst);
2181c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
2191c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			break;
2201c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
221cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZX:
222bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
223bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
224bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
225bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
226cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZUX:
227bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
228bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
229bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
230bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2318e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
232bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2338e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
234bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
235bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
2368e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
237bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
238bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
239cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MFSPR:
240bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
241bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
242bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
243bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
244bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
2458e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break;
246bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
2478e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break;
248bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_PVR:
2498e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
25006579dd9c12f36ac575460a226d2020d84a0128bLiu Yu			case SPRN_PIR:
2518e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
252513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0:
2538e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, 0); break;
254bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
255bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: mftb and TBRL/TBWL are user-accessible, so
256bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * the guest can always access the real TB anyways.
257bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * In fact, we probably will never see these traps. */
258bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL:
2598e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
260bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU:
2618e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb()); break;
262bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
263bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
2648e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break;
265bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
2668e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break;
267bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
2688e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break;
269bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
2708e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break;
271bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: SPRG4-7 are user-readable, so we don't get
272bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * a trap. */
273bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2749a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			case SPRN_DEC:
2759a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			{
276513579e3a391a3874c478a8493080822069976e8Alexander Graf				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
2778e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
278689fd14ae9b2af5c6862ddc11d4791ec9a938cb3Joe Perches				pr_debug("mfDEC: %x - %llx = %lx\n",
2798e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					 vcpu->arch.dec, jd,
2808e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					 kvmppc_get_gpr(vcpu, rt));
2819a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf				break;
2829a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			}
283bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
28475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
28575f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL) {
28675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mfspr: unknown spr %x\n", sprn);
2878e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					kvmppc_set_gpr(vcpu, rt, 0);
28875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				}
289bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
290bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
291bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
292bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
293cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHX:
294bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
295bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
296bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
297bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
298bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2998e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
300bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
301bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
302bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
303cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHUX:
304bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
305bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
306bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
307bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
3088e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
309bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
3108e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
311bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
312bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
314bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
3158e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
316bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
317bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
318cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MTSPR:
319bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
320bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
321bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
322bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
3238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break;
324bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
3258e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break;
326bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
327bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* XXX We need to context-switch the timebase for
328bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * watchdog and FIT. */
329bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL: break;
330bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU: break;
331bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
332513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0: break;
333513579e3a391a3874c478a8493080822069976e8Alexander Graf
334bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_DEC:
3358e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
336bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				kvmppc_emulate_dec(vcpu);
337bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
338bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
339bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
3408e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break;
341bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
3428e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break;
343bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
3448e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break;
345bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
3468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break;
347bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
348bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
34975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
35075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL)
35175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mtspr: unknown spr %x\n", sprn);
352bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
353bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
354bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
355bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
356cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_DCBI:
357bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Do nothing. The guest is performing dcbi because
358bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * hardware DMA is not snooped by the dcache, but
359bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * emulated DMA either goes through the dcache as
360bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * normal writes, or the host kernel has handled dcache
361bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * coherence. */
362bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
363bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
364cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWBRX:
365bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
366bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
367bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
368bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
369cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_TLBSYNC:
370bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
371bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
372cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWBRX:
373bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
374bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
375bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
376bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
377bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3788e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
379bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               4, 0);
380bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
381bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
382cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHBRX:
383bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
384bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
385bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
386bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
387cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHBRX:
388bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
389bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
390bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
391bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
392bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3938e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
394bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 0);
395bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
396bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
397bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		default:
39875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			/* Attempt core-specific emulation below. */
399bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = EMULATE_FAIL;
400bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		}
401bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
402bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
403cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZ:
404bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
405bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
406bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
407bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
408cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZU:
409bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
410bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
411bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
4128e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
413bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
414bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
415cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZ:
416bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
417bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
418bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
419bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
420cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZU:
421bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
422bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
423bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
4248e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
425bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
426bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
427cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STW:
428bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4298e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4308e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
431bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
432bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
433bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
434cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STWU:
435bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
436bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4378e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4388e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
439bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
4408e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
441bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
442bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
443cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STB:
444bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4458e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
447bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
448bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
449bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
450cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STBU:
451bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
452bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4538e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4548e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
455bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
4568e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
457bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
458bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
459cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZ:
460bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
461bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
462bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
463bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
464cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZU:
465bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
466bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
467bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
4688e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
469bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
470bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
4713587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf	case OP_LHA:
4723587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		rt = get_rt(inst);
4733587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
4743587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		break;
4753587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf
4763587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf	case OP_LHAU:
4773587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		ra = get_ra(inst);
4783587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		rt = get_rt(inst);
4793587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
4803587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
4813587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		break;
4823587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf
483cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STH:
484bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4858e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4868e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
487bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
488bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
489bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
490cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STHU:
491bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
492bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4938e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4948e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
495bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
4968e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
497bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
498bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
499bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	default:
500bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = EMULATE_FAIL;
50175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	}
50275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard
50375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	if (emulated == EMULATE_FAIL) {
50475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance);
50537f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf		if (emulated == EMULATE_AGAIN) {
50637f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf			advance = 0;
50737f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf		} else if (emulated == EMULATE_FAIL) {
50875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			advance = 0;
50975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
51075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			       "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
5115f2b105a1d6a137c8cfb2792b79128db965880a8Alexander Graf			kvmppc_core_queue_program(vcpu, 0);
51275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		}
513bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
514bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
515c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated);
5163b4bd7969f7b61a1ab455bff084ee4f0a2411055Christian Ehrhardt
517c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	/* Advance past emulated instruction. */
518bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	if (advance)
519c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf		kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
520bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
521bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	return emulated;
522bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
523