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
16dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood * Copyright 2011 Freescale Semiconductor, Inc.
17bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
18bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
20bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
21bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/jiffies.h>
22544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf#include <linux/hrtimer.h>
23bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/types.h>
24bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/string.h>
25bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <linux/kvm_host.h>
26bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard#include <asm/reg.h>
28bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/time.h>
29bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/byteorder.h>
30bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard#include <asm/kvm_ppc.h>
31c381a04313e7c0fb04246b1ff711e0b5726de6c0Hollis Blanchard#include <asm/disassemble.h>
3273e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard#include "timing.h"
3346f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti#include "trace.h"
34bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
35cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_TRAP 3
36513579e3a391a3874c478a8493080822069976e8Alexander Graf#define OP_TRAP_64 2
37cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
38cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWZX      23
39cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LBZX      87
40cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWX      151
41cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBX      215
421c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf#define OP_31_XOP_LBZUX     119
43cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBUX     247
44cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZX      279
45cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZUX     311
46cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MFSPR     339
471c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf#define OP_31_XOP_LHAX      343
48cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHX      407
49cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHUX     439
50cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MTSPR     467
51cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_DCBI      470
52cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWBRX     534
53cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_TLBSYNC   566
54cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWBRX    662
55cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHBRX     790
56cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHBRX    918
57cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
58cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZ  32
59cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZU 33
60cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZ  34
61cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZU 35
62cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STW  36
63cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STWU 37
64cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STB  38
65cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STBU 39
66cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZ  40
67cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZU 41
683587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf#define OP_LHA  42
693587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf#define OP_LHAU 43
70cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STH  44
71cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STHU 45
72cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard
7375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchardvoid kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
74bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
75544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	unsigned long dec_nsec;
76dc2babfea592e633cf3890294af6545609b466beBharat Bhushan	unsigned long long dec_time;
779a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf
78544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf	pr_debug("mtDEC: %x\n", vcpu->arch.dec);
79dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
80dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
8100c3a37ca332f54f2187720e51f7c0e18e91d7c9Alexander Graf#ifdef CONFIG_PPC_BOOK3S
827706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	/* mtdec lowers the interrupt line when positive. */
837706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf	kvmppc_core_dequeue_dec(vcpu);
847706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf
85513579e3a391a3874c478a8493080822069976e8Alexander Graf	/* POWER4+ triggers a dec interrupt if the value is < 0 */
86513579e3a391a3874c478a8493080822069976e8Alexander Graf	if (vcpu->arch.dec & 0x80000000) {
87513579e3a391a3874c478a8493080822069976e8Alexander Graf		kvmppc_core_queue_dec(vcpu);
88513579e3a391a3874c478a8493080822069976e8Alexander Graf		return;
89513579e3a391a3874c478a8493080822069976e8Alexander Graf	}
90513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
91dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
92dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood#ifdef CONFIG_BOOKE
93dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	/* On BOOKE, DEC = 0 is as good as decrementer not enabled */
94dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	if (vcpu->arch.dec == 0)
95dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood		return;
96dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood#endif
97dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
98dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	/*
99dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	 * The decrementer ticks at the same rate as the timebase, so
100dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	 * that's how we convert the guest DEC value to the number of
101dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	 * host ticks.
102dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	 */
103dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
104dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	dec_time = vcpu->arch.dec;
105dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	dec_time *= 1000;
106dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	do_div(dec_time, tb_ticks_per_usec);
107dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	dec_nsec = do_div(dec_time, NSEC_PER_SEC);
108dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	hrtimer_start(&vcpu->arch.dec_timer,
109dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood		ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
110dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	vcpu->arch.dec_jiffies = get_tb();
111bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
112bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
1135ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Woodu32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
1145ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood{
1155ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood	u64 jd = tb - vcpu->arch.dec_jiffies;
116dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
117dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood#ifdef CONFIG_BOOKE
118dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood	if (vcpu->arch.dec < jd)
119dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood		return 0;
120dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood#endif
121dfd4d47e9a71c5a35eb67a44cd311efbe1846b7eScott Wood
1225ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood	return vcpu->arch.dec - jd;
1235ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood}
1245ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood
125bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/* XXX to do:
126bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhax
127bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhaux
128bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswx
129bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswi
130bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswx
131bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswi
132bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lha
133bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhau
134bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lmw
135bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stmw
136bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard *
137bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * XXX is_bigendian should depend on MMU mapping or MSR[LE]
138bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */
13975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard/* XXX Should probably auto-generate instruction decoding for a particular core
14075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard * from opcode tables in the future. */
141bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchardint kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
142bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{
143c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	u32 inst = kvmppc_get_last_inst(vcpu);
144bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	u32 ea;
145bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int ra;
146bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rb;
147bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rs;
148bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int rt;
149bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int sprn;
150bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	enum emulation_result emulated = EMULATE_DONE;
151bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	int advance = 1;
152bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
15373e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	/* this default type might be overwritten by subcategories */
15473e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard	kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
15573e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard
156689fd14ae9b2af5c6862ddc11d4791ec9a938cb3Joe Perches	pr_debug("Emulating opcode %d / %d\n", get_op(inst), get_xop(inst));
157513579e3a391a3874c478a8493080822069976e8Alexander Graf
158bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	switch (get_op(inst)) {
159cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_TRAP:
16000c3a37ca332f54f2187720e51f7c0e18e91d7c9Alexander Graf#ifdef CONFIG_PPC_BOOK3S
161513579e3a391a3874c478a8493080822069976e8Alexander Graf	case OP_TRAP_64:
162daf5e27109c8c16c987e955cc6abbbc0af050eddLiu Yu		kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
163513579e3a391a3874c478a8493080822069976e8Alexander Graf#else
164b59049720dd95021dfe0d9f4e1fa9458a67cfe29Scott Wood		kvmppc_core_queue_program(vcpu,
165b59049720dd95021dfe0d9f4e1fa9458a67cfe29Scott Wood					  vcpu->arch.shared->esr | ESR_PTR);
166513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif
167bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		advance = 0;
168bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
169bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
170bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	case 31:
171bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		switch (get_xop(inst)) {
172bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
173cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWZX:
174ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rt = get_rt(inst);
175ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
176ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
177ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
178cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LBZX:
179bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
180bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
181bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
182bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
1831c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf		case OP_31_XOP_LBZUX:
1841c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rt = get_rt(inst);
1851c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			ra = get_ra(inst);
1861c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rb = get_rb(inst);
1871c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
1881c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
1891c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			if (ra)
1901c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
1911c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
1921c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
1931c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
1941c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			break;
1951c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
196cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWX:
197ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			rs = get_rs(inst);
198ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
1998e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
200ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			                               4, 1);
201ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard			break;
202ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard
203cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBX:
204bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
205bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2068e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
207bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
208bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
209bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
210cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STBUX:
211bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
212bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
213bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
214bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2158e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
216bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2178e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
218bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
219bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
2208e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
221bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               1, 1);
2228e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, rs, ea);
223bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
224bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2251c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf		case OP_31_XOP_LHAX:
2261c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			rt = get_rt(inst);
2271c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
2281c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf			break;
2291c85e73303fa70cd6bc2bf138484acb4ffe30efdAlexander Graf
230cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZX:
231bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
232bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
233bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
234bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
235cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHZUX:
236bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
237bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
238bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
239bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2408e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
241bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
2428e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
243bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
244bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
2458e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
246bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
247bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
248cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MFSPR:
249bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
250bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
251bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
252bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
253bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
254de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr0);
255de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				break;
256bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
257de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr1);
258de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				break;
259bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_PVR:
2608e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break;
26106579dd9c12f36ac575460a226d2020d84a0128bLiu Yu			case SPRN_PIR:
2628e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break;
263513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0:
2648e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, 0); break;
265bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
266bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: mftb and TBRL/TBWL are user-accessible, so
267bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * the guest can always access the real TB anyways.
268bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * In fact, we probably will never see these traps. */
269bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL:
2708e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break;
271bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU:
2728e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				kvmppc_set_gpr(vcpu, rt, get_tb()); break;
273bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
274bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
275a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg0);
276a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
277bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
278a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg1);
279a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
280bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
281a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg2);
282a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
283bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
284a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg3);
285a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
286bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Note: SPRG4-7 are user-readable, so we don't get
287bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * a trap. */
288bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
2899a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			case SPRN_DEC:
2909a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			{
2915ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood				kvmppc_set_gpr(vcpu, rt,
2925ce941ee4258b836cf818d2ac159d8cf3ebad648Scott Wood					       kvmppc_get_dec(vcpu, get_tb()));
2939a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf				break;
2949a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf			}
295bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
29675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt);
29775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL) {
29875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mfspr: unknown spr %x\n", sprn);
2998e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					kvmppc_set_gpr(vcpu, rt, 0);
30075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				}
301bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
302bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
30349ea06957bf637b28aa338fba26432d5bafdeb99Scott Wood			kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
304bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
305bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
306cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHX:
307bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
308bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
309bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
310bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
311bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3128e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
313bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
314bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
315bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
316cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHUX:
317bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
318bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
319bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
320bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
3218e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			ea = kvmppc_get_gpr(vcpu, rb);
322bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			if (ra)
3238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				ea += kvmppc_get_gpr(vcpu, ra);
324bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
325bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3268e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
327bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 1);
3288e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf			kvmppc_set_gpr(vcpu, ra, ea);
329bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
330bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
331cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_MTSPR:
332bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			sprn = get_sprn(inst);
333bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
334bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			switch (sprn) {
335bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR0:
336de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				vcpu->arch.shared->srr0 = kvmppc_get_gpr(vcpu, rs);
337de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				break;
338bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SRR1:
339de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				vcpu->arch.shared->srr1 = kvmppc_get_gpr(vcpu, rs);
340de7906c36ca1e22a3e3600e95c6a4e2c1e4e2e9cAlexander Graf				break;
341bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
342bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* XXX We need to context-switch the timebase for
343bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * watchdog and FIT. */
344bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWL: break;
345bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_TBWU: break;
346bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
347513579e3a391a3874c478a8493080822069976e8Alexander Graf			case SPRN_MSSSR0: break;
348513579e3a391a3874c478a8493080822069976e8Alexander Graf
349bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_DEC:
3508e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf				vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs);
351bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				kvmppc_emulate_dec(vcpu);
352bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
353bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
354bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG0:
355a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				vcpu->arch.shared->sprg0 = kvmppc_get_gpr(vcpu, rs);
356a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
357bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG1:
358a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				vcpu->arch.shared->sprg1 = kvmppc_get_gpr(vcpu, rs);
359a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
360bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG2:
361a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				vcpu->arch.shared->sprg2 = kvmppc_get_gpr(vcpu, rs);
362a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
363bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			case SPRN_SPRG3:
364a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				vcpu->arch.shared->sprg3 = kvmppc_get_gpr(vcpu, rs);
365a73a9599e03eef1324d5aeecaebc1b339d2e1664Alexander Graf				break;
366bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
367bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			default:
36875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs);
36975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard				if (emulated == EMULATE_FAIL)
37075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard					printk("mtspr: unknown spr %x\n", sprn);
371bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard				break;
372bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			}
37349ea06957bf637b28aa338fba26432d5bafdeb99Scott Wood			kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
374bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
375bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
376cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_DCBI:
377bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			/* Do nothing. The guest is performing dcbi because
378bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * hardware DMA is not snooped by the dcache, but
379bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * emulated DMA either goes through the dcache as
380bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * normal writes, or the host kernel has handled dcache
381bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			 * coherence. */
382bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
383bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
384cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LWBRX:
385bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
386bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
387bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
388bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
389cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_TLBSYNC:
390bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
391bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
392cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STWBRX:
393bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
394bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
395bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
396bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
397bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
3988e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
399bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               4, 0);
400bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
401bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
402cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_LHBRX:
403bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rt = get_rt(inst);
404bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
405bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
406bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
407cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard		case OP_31_XOP_STHBRX:
408bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rs = get_rs(inst);
409bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			ra = get_ra(inst);
410bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			rb = get_rb(inst);
411bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
412bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = kvmppc_handle_store(run, vcpu,
4138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf						       kvmppc_get_gpr(vcpu, rs),
414bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			                               2, 0);
415bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			break;
416bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
417bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		default:
41875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			/* Attempt core-specific emulation below. */
419bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard			emulated = EMULATE_FAIL;
420bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		}
421bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
422bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
423cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZ:
424bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
425bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
426bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
427bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
428cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LWZU:
429bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
430bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
431bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
4328e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
433bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
434bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
435cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZ:
436bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
437bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
438bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
439bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
440cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LBZU:
441bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
442bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
443bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
4448e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
445bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
446bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
447cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STW:
448bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4498e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4508e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
451bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
452bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
453bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
454cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STWU:
455bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
456bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4578e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4588e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
459bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               4, 1);
4608e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
461bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
462bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
463cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STB:
464bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4658e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4668e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
467bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
468bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
469bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
470cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STBU:
471bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
472bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
4738e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
4748e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
475bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               1, 1);
4768e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
477bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
478bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
479cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZ:
480bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
481bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
482bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
483bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
484cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_LHZU:
485bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
486bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rt = get_rt(inst);
487bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
4888e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
489bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
490bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
4913587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf	case OP_LHA:
4923587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		rt = get_rt(inst);
4933587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
4943587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		break;
4953587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf
4963587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf	case OP_LHAU:
4973587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		ra = get_ra(inst);
4983587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		rt = get_rt(inst);
4993587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
5003587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
5013587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf		break;
5023587d5348ced089666c51411bd9d771fb0b072cfAlexander Graf
503cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STH:
504bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
5058e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
5068e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
507bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
508bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
509bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
510cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard	case OP_STHU:
511bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		ra = get_ra(inst);
512bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		rs = get_rs(inst);
5138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		emulated = kvmppc_handle_store(run, vcpu,
5148e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf					       kvmppc_get_gpr(vcpu, rs),
515bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		                               2, 1);
5168e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf		kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
517bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		break;
518bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
519bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	default:
520bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard		emulated = EMULATE_FAIL;
52175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	}
52275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard
52375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard	if (emulated == EMULATE_FAIL) {
52475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance);
52537f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf		if (emulated == EMULATE_AGAIN) {
52637f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf			advance = 0;
52737f5bca64e206ed97e53f734d7de5b7c5ade3578Alexander Graf		} else if (emulated == EMULATE_FAIL) {
52875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			advance = 0;
52975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			printk(KERN_ERR "Couldn't emulate instruction 0x%08x "
53075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard			       "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst));
5315f2b105a1d6a137c8cfb2792b79128db965880a8Alexander Graf			kvmppc_core_queue_program(vcpu, 0);
53275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard		}
533bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	}
534bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
535c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	trace_kvm_ppc_instr(inst, kvmppc_get_pc(vcpu), emulated);
5363b4bd7969f7b61a1ab455bff084ee4f0a2411055Christian Ehrhardt
537c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf	/* Advance past emulated instruction. */
538bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	if (advance)
539c7f38f46f2a98d232147e47284cb4e7363296a3eAlexander Graf		kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) + 4);
540bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard
541bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard	return emulated;
542bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard}
543