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