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