emulate.c revision 8e5b26b55a8b6aee2c789b1d20ec715f9e4bea5c
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 41cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STBUX 247 42cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZX 279 43cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHZUX 311 44cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MFSPR 339 45cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHX 407 46cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHUX 439 47cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_MTSPR 467 48cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_DCBI 470 49cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LWBRX 534 50cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_TLBSYNC 566 51cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STWBRX 662 52cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_LHBRX 790 53cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_31_XOP_STHBRX 918 54cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard 55cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZ 32 56cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LWZU 33 57cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZ 34 58cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LBZU 35 59cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STW 36 60cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STWU 37 61cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STB 38 62cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STBU 39 63cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZ 40 64cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_LHZU 41 65cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STH 44 66cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard#define OP_STHU 45 67cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard 68513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64 69513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu) 70513579e3a391a3874c478a8493080822069976e8Alexander Graf{ 71513579e3a391a3874c478a8493080822069976e8Alexander Graf return 1; 72513579e3a391a3874c478a8493080822069976e8Alexander Graf} 73513579e3a391a3874c478a8493080822069976e8Alexander Graf#else 74513579e3a391a3874c478a8493080822069976e8Alexander Grafstatic int kvmppc_dec_enabled(struct kvm_vcpu *vcpu) 75513579e3a391a3874c478a8493080822069976e8Alexander Graf{ 76513579e3a391a3874c478a8493080822069976e8Alexander Graf return vcpu->arch.tcr & TCR_DIE; 77513579e3a391a3874c478a8493080822069976e8Alexander Graf} 78513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif 79513579e3a391a3874c478a8493080822069976e8Alexander Graf 8075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchardvoid kvmppc_emulate_dec(struct kvm_vcpu *vcpu) 81bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{ 82544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf unsigned long dec_nsec; 839a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf 84544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf pr_debug("mtDEC: %x\n", vcpu->arch.dec); 85513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64 867706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf /* mtdec lowers the interrupt line when positive. */ 877706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf kvmppc_core_dequeue_dec(vcpu); 887706664d39a8eb8555408a24b1f17bd2086189c6Alexander Graf 89513579e3a391a3874c478a8493080822069976e8Alexander Graf /* POWER4+ triggers a dec interrupt if the value is < 0 */ 90513579e3a391a3874c478a8493080822069976e8Alexander Graf if (vcpu->arch.dec & 0x80000000) { 91544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf hrtimer_try_to_cancel(&vcpu->arch.dec_timer); 92513579e3a391a3874c478a8493080822069976e8Alexander Graf kvmppc_core_queue_dec(vcpu); 93513579e3a391a3874c478a8493080822069976e8Alexander Graf return; 94513579e3a391a3874c478a8493080822069976e8Alexander Graf } 95513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif 96513579e3a391a3874c478a8493080822069976e8Alexander Graf if (kvmppc_dec_enabled(vcpu)) { 97bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard /* The decrementer ticks at the same rate as the timebase, so 98bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * that's how we convert the guest DEC value to the number of 99bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * host ticks. */ 100bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 101544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf hrtimer_try_to_cancel(&vcpu->arch.dec_timer); 102544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf dec_nsec = vcpu->arch.dec; 103544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf dec_nsec *= 1000; 104544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf dec_nsec /= tb_ticks_per_usec; 105544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf hrtimer_start(&vcpu->arch.dec_timer, ktime_set(0, dec_nsec), 106544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf HRTIMER_MODE_REL); 107513579e3a391a3874c478a8493080822069976e8Alexander Graf vcpu->arch.dec_jiffies = get_tb(); 108bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } else { 109544c6761bb05a1dd19a39cb9bed096273f9bdb36Alexander Graf hrtimer_try_to_cancel(&vcpu->arch.dec_timer); 110bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } 111bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard} 112bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 113bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard/* XXX to do: 114bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhax 115bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhaux 116bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswx 117bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lswi 118bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswx 119bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stswi 120bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lha 121bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lhau 122bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * lmw 123bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * stmw 124bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * 125bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * XXX is_bigendian should depend on MMU mapping or MSR[LE] 126bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard */ 12775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard/* XXX Should probably auto-generate instruction decoding for a particular core 12875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard * from opcode tables in the future. */ 129bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchardint kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) 130bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard{ 131bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard u32 inst = vcpu->arch.last_inst; 132bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard u32 ea; 133bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int ra; 134bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int rb; 135bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int rs; 136bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int rt; 137bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int sprn; 138bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard enum emulation_result emulated = EMULATE_DONE; 139bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard int advance = 1; 140bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 14173e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard /* this default type might be overwritten by subcategories */ 14273e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); 14373e75b416ffcfa3a84952d8e389a0eca080f00e1Hollis Blanchard 144513579e3a391a3874c478a8493080822069976e8Alexander Graf pr_debug(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); 145513579e3a391a3874c478a8493080822069976e8Alexander Graf 146bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard switch (get_op(inst)) { 147cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_TRAP: 148513579e3a391a3874c478a8493080822069976e8Alexander Graf#ifdef CONFIG_PPC64 149513579e3a391a3874c478a8493080822069976e8Alexander Graf case OP_TRAP_64: 150513579e3a391a3874c478a8493080822069976e8Alexander Graf#else 151fcfdbd266a41d3e41d17666de410a24995fde03aHollis Blanchard vcpu->arch.esr |= ESR_PTR; 152513579e3a391a3874c478a8493080822069976e8Alexander Graf#endif 1539dd921cfea734409a931ccc6eafd7f09850311e9Hollis Blanchard kvmppc_core_queue_program(vcpu); 154bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard advance = 0; 155bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 156bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 157bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case 31: 158bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard switch (get_xop(inst)) { 159bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 160cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LWZX: 161ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard rt = get_rt(inst); 162ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 163ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard break; 164ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard 165cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LBZX: 166bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 167bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 168bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 169bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 170cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STWX: 171ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard rs = get_rs(inst); 172ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 1738e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 174ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard 4, 1); 175ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard break; 176ac3cd34e4eb9e3dccaec8e586c073ba2660b322fHollis Blanchard 177cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STBX: 178bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 179bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 1808e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 181bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 1, 1); 182bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 183bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 184cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STBUX: 185bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 186bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 187bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 188bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 1898e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea = kvmppc_get_gpr(vcpu, rb); 190bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard if (ra) 1918e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea += kvmppc_get_gpr(vcpu, ra); 192bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 193bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 1948e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 195bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 1, 1); 1968e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rs, ea); 197bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 198bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 199cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LHZX: 200bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 201bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 202bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 203bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 204cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LHZUX: 205bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 206bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 207bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 208bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2098e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea = kvmppc_get_gpr(vcpu, rb); 210bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard if (ra) 2118e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea += kvmppc_get_gpr(vcpu, ra); 212bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 213bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 2148e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, ea); 215bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 216bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 217cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_MFSPR: 218bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard sprn = get_sprn(inst); 219bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 220bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 221bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard switch (sprn) { 222bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SRR0: 2238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr0); break; 224bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SRR1: 2258e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.srr1); break; 226bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_PVR: 2278e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break; 22806579dd9c12f36ac575460a226d2020d84a0128bLiu Yu case SPRN_PIR: 2298e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break; 230513579e3a391a3874c478a8493080822069976e8Alexander Graf case SPRN_MSSSR0: 2318e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, 0); break; 232bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 233bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard /* Note: mftb and TBRL/TBWL are user-accessible, so 234bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * the guest can always access the real TB anyways. 235bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * In fact, we probably will never see these traps. */ 236bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_TBWL: 2378e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break; 238bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_TBWU: 2398e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, get_tb()); break; 240bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 241bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG0: 2428e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg0); break; 243bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG1: 2448e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg1); break; 245bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG2: 2468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg2); break; 247bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG3: 2488e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.sprg3); break; 249bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard /* Note: SPRG4-7 are user-readable, so we don't get 250bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * a trap. */ 251bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2529a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf case SPRN_DEC: 2539a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf { 254513579e3a391a3874c478a8493080822069976e8Alexander Graf u64 jd = get_tb() - vcpu->arch.dec_jiffies; 2558e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd); 2568e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf pr_debug(KERN_INFO "mfDEC: %x - %llx = %lx\n", 2578e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.dec, jd, 2588e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rt)); 2599a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf break; 2609a7a9b09fee8487003df012d9af4b227b3661e4dAlexander Graf } 261bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard default: 26275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt); 26375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard if (emulated == EMULATE_FAIL) { 26475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard printk("mfspr: unknown spr %x\n", sprn); 2658e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, rt, 0); 26675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard } 267bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 268bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } 269bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 270bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 271cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STHX: 272bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 273bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 274bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 275bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 276bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 2778e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 278bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2, 1); 279bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 280bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 281cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STHUX: 282bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 283bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 284bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 285bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2868e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea = kvmppc_get_gpr(vcpu, rb); 287bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard if (ra) 2888e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf ea += kvmppc_get_gpr(vcpu, ra); 289bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 290bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 2918e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 292bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2, 1); 2938e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, ea); 294bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 295bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 296cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_MTSPR: 297bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard sprn = get_sprn(inst); 298bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 299bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard switch (sprn) { 300bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SRR0: 3018e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.srr0 = kvmppc_get_gpr(vcpu, rs); break; 302bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SRR1: 3038e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.srr1 = kvmppc_get_gpr(vcpu, rs); break; 304bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 305bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard /* XXX We need to context-switch the timebase for 306bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * watchdog and FIT. */ 307bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_TBWL: break; 308bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_TBWU: break; 309bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 310513579e3a391a3874c478a8493080822069976e8Alexander Graf case SPRN_MSSSR0: break; 311513579e3a391a3874c478a8493080822069976e8Alexander Graf 312bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_DEC: 3138e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs); 314bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard kvmppc_emulate_dec(vcpu); 315bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 316bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 317bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG0: 3188e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.sprg0 = kvmppc_get_gpr(vcpu, rs); break; 319bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG1: 3208e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.sprg1 = kvmppc_get_gpr(vcpu, rs); break; 321bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG2: 3228e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.sprg2 = kvmppc_get_gpr(vcpu, rs); break; 323bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard case SPRN_SPRG3: 3248e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf vcpu->arch.sprg3 = kvmppc_get_gpr(vcpu, rs); break; 325bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 326bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard default: 32775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs); 32875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard if (emulated == EMULATE_FAIL) 32975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard printk("mtspr: unknown spr %x\n", sprn); 330bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 331bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } 332bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 333bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 334cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_DCBI: 335bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard /* Do nothing. The guest is performing dcbi because 336bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * hardware DMA is not snooped by the dcache, but 337bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * emulated DMA either goes through the dcache as 338bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * normal writes, or the host kernel has handled dcache 339bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard * coherence. */ 340bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 341bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 342cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LWBRX: 343bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 344bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); 345bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 346bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 347cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_TLBSYNC: 348bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 349bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 350cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STWBRX: 351bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 352bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 353bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 354bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 355bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 3568e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 357bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 4, 0); 358bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 359bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 360cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_LHBRX: 361bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 362bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); 363bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 364bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 365cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_31_XOP_STHBRX: 366bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 367bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 368bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rb = get_rb(inst); 369bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 370bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_store(run, vcpu, 3718e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 372bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2, 0); 373bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 374bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 375bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard default: 37675f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard /* Attempt core-specific emulation below. */ 377bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = EMULATE_FAIL; 378bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } 379bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 380bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 381cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LWZ: 382bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 383bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 384bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 385bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 386cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LWZU: 387bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 388bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 389bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 3908e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 391bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 392bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 393cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LBZ: 394bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 395bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 396bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 397bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 398cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LBZU: 399bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 400bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 401bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 4028e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 403bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 404bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 405cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STW: 406bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4078e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4088e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 409bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 4, 1); 410bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 411bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 412cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STWU: 413bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 414bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4158e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4168e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 417bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 4, 1); 4188e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 419bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 420bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 421cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STB: 422bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4238e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4248e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 425bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 1, 1); 426bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 427bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 428cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STBU: 429bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 430bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4318e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4328e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 433bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 1, 1); 4348e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 435bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 436bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 437cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LHZ: 438bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 439bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 440bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 441bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 442cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_LHZU: 443bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 444bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rt = get_rt(inst); 445bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 4468e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 447bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 448bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 449cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STH: 450bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4518e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4528e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 453bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2, 1); 454bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 455bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 456cea5d8c9de669e30ed6d60930318376d5cc42e9eHollis Blanchard case OP_STHU: 457bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard ra = get_ra(inst); 458bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard rs = get_rs(inst); 4598e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf emulated = kvmppc_handle_store(run, vcpu, 4608e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_get_gpr(vcpu, rs), 461bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 2, 1); 4628e5b26b55a8b6aee2c789b1d20ec715f9e4bea5cAlexander Graf kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 463bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard break; 464bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 465bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard default: 466bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard emulated = EMULATE_FAIL; 46775f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard } 46875f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard 46975f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard if (emulated == EMULATE_FAIL) { 47075f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); 47175f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard if (emulated == EMULATE_FAIL) { 47275f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard advance = 0; 47375f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard printk(KERN_ERR "Couldn't emulate instruction 0x%08x " 47475f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); 47575f74f0dbe086c239b4b0cc5ed75b903ea3e663fHollis Blanchard } 476bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard } 477bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 47846f43c6ee022c3aeb9686b104234b9f27fac03c2Marcelo Tosatti trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated); 4793b4bd7969f7b61a1ab455bff084ee4f0a2411055Christian Ehrhardt 480bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard if (advance) 481bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard vcpu->arch.pc += 4; /* Advance past emulated instruction. */ 482bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard 483bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard return emulated; 484bbf45ba57eaec56569918a8bab96ab653bd45ec1Hollis Blanchard} 485