1bc8080cbSHollis Blanchard /* 2bc8080cbSHollis Blanchard * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. 3bc8080cbSHollis Blanchard * 4bc8080cbSHollis Blanchard * Author: Yu Liu, <yu.liu@freescale.com> 5bc8080cbSHollis Blanchard * 6bc8080cbSHollis Blanchard * Description: 7bc8080cbSHollis Blanchard * This file is derived from arch/powerpc/kvm/44x_emulate.c, 8bc8080cbSHollis Blanchard * by Hollis Blanchard <hollisb@us.ibm.com>. 9bc8080cbSHollis Blanchard * 10bc8080cbSHollis Blanchard * This program is free software; you can redistribute it and/or modify 11bc8080cbSHollis Blanchard * it under the terms of the GNU General Public License, version 2, as 12bc8080cbSHollis Blanchard * published by the Free Software Foundation. 13bc8080cbSHollis Blanchard */ 14bc8080cbSHollis Blanchard 15bc8080cbSHollis Blanchard #include <asm/kvm_ppc.h> 16bc8080cbSHollis Blanchard #include <asm/disassemble.h> 17bc8080cbSHollis Blanchard #include <asm/kvm_e500.h> 18bc8080cbSHollis Blanchard 19bc8080cbSHollis Blanchard #include "booke.h" 20bc8080cbSHollis Blanchard #include "e500_tlb.h" 21bc8080cbSHollis Blanchard 22bc8080cbSHollis Blanchard #define XOP_TLBIVAX 786 23bc8080cbSHollis Blanchard #define XOP_TLBSX 914 24bc8080cbSHollis Blanchard #define XOP_TLBRE 946 25bc8080cbSHollis Blanchard #define XOP_TLBWE 978 26bc8080cbSHollis Blanchard 27bc8080cbSHollis Blanchard int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 28bc8080cbSHollis Blanchard unsigned int inst, int *advance) 29bc8080cbSHollis Blanchard { 30bc8080cbSHollis Blanchard int emulated = EMULATE_DONE; 31bc8080cbSHollis Blanchard int ra; 32bc8080cbSHollis Blanchard int rb; 33bc8080cbSHollis Blanchard 34bc8080cbSHollis Blanchard switch (get_op(inst)) { 35bc8080cbSHollis Blanchard case 31: 36bc8080cbSHollis Blanchard switch (get_xop(inst)) { 37bc8080cbSHollis Blanchard 38bc8080cbSHollis Blanchard case XOP_TLBRE: 39bc8080cbSHollis Blanchard emulated = kvmppc_e500_emul_tlbre(vcpu); 40bc8080cbSHollis Blanchard break; 41bc8080cbSHollis Blanchard 42bc8080cbSHollis Blanchard case XOP_TLBWE: 43bc8080cbSHollis Blanchard emulated = kvmppc_e500_emul_tlbwe(vcpu); 44bc8080cbSHollis Blanchard break; 45bc8080cbSHollis Blanchard 46bc8080cbSHollis Blanchard case XOP_TLBSX: 47bc8080cbSHollis Blanchard rb = get_rb(inst); 48bc8080cbSHollis Blanchard emulated = kvmppc_e500_emul_tlbsx(vcpu,rb); 49bc8080cbSHollis Blanchard break; 50bc8080cbSHollis Blanchard 51bc8080cbSHollis Blanchard case XOP_TLBIVAX: 52bc8080cbSHollis Blanchard ra = get_ra(inst); 53bc8080cbSHollis Blanchard rb = get_rb(inst); 54bc8080cbSHollis Blanchard emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb); 55bc8080cbSHollis Blanchard break; 56bc8080cbSHollis Blanchard 57bc8080cbSHollis Blanchard default: 58bc8080cbSHollis Blanchard emulated = EMULATE_FAIL; 59bc8080cbSHollis Blanchard } 60bc8080cbSHollis Blanchard 61bc8080cbSHollis Blanchard break; 62bc8080cbSHollis Blanchard 63bc8080cbSHollis Blanchard default: 64bc8080cbSHollis Blanchard emulated = EMULATE_FAIL; 65bc8080cbSHollis Blanchard } 66bc8080cbSHollis Blanchard 67bc8080cbSHollis Blanchard if (emulated == EMULATE_FAIL) 68bc8080cbSHollis Blanchard emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance); 69bc8080cbSHollis Blanchard 70bc8080cbSHollis Blanchard return emulated; 71bc8080cbSHollis Blanchard } 72bc8080cbSHollis Blanchard 73bc8080cbSHollis Blanchard int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 74bc8080cbSHollis Blanchard { 75bc8080cbSHollis Blanchard struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 76bc8080cbSHollis Blanchard int emulated = EMULATE_DONE; 778e5b26b5SAlexander Graf ulong spr_val = kvmppc_get_gpr(vcpu, rs); 78bc8080cbSHollis Blanchard 79bc8080cbSHollis Blanchard switch (sprn) { 80bc8080cbSHollis Blanchard case SPRN_PID: 81bc8080cbSHollis Blanchard vcpu_e500->pid[0] = vcpu->arch.shadow_pid = 828e5b26b5SAlexander Graf vcpu->arch.pid = spr_val; 83bc8080cbSHollis Blanchard break; 84bc8080cbSHollis Blanchard case SPRN_PID1: 858e5b26b5SAlexander Graf vcpu_e500->pid[1] = spr_val; break; 86bc8080cbSHollis Blanchard case SPRN_PID2: 878e5b26b5SAlexander Graf vcpu_e500->pid[2] = spr_val; break; 88bc8080cbSHollis Blanchard case SPRN_MAS0: 898e5b26b5SAlexander Graf vcpu_e500->mas0 = spr_val; break; 90bc8080cbSHollis Blanchard case SPRN_MAS1: 918e5b26b5SAlexander Graf vcpu_e500->mas1 = spr_val; break; 92bc8080cbSHollis Blanchard case SPRN_MAS2: 938e5b26b5SAlexander Graf vcpu_e500->mas2 = spr_val; break; 94bc8080cbSHollis Blanchard case SPRN_MAS3: 958e5b26b5SAlexander Graf vcpu_e500->mas3 = spr_val; break; 96bc8080cbSHollis Blanchard case SPRN_MAS4: 978e5b26b5SAlexander Graf vcpu_e500->mas4 = spr_val; break; 98bc8080cbSHollis Blanchard case SPRN_MAS6: 998e5b26b5SAlexander Graf vcpu_e500->mas6 = spr_val; break; 100bc8080cbSHollis Blanchard case SPRN_MAS7: 1018e5b26b5SAlexander Graf vcpu_e500->mas7 = spr_val; break; 102bc8080cbSHollis Blanchard case SPRN_L1CSR1: 1038e5b26b5SAlexander Graf vcpu_e500->l1csr1 = spr_val; break; 104bc8080cbSHollis Blanchard case SPRN_HID0: 1058e5b26b5SAlexander Graf vcpu_e500->hid0 = spr_val; break; 106bc8080cbSHollis Blanchard case SPRN_HID1: 1078e5b26b5SAlexander Graf vcpu_e500->hid1 = spr_val; break; 108bc8080cbSHollis Blanchard 109b0a1835dSLiu Yu case SPRN_MMUCSR0: 110b0a1835dSLiu Yu emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500, 1118e5b26b5SAlexander Graf spr_val); 112b0a1835dSLiu Yu break; 113b0a1835dSLiu Yu 114bb3a8a17SHollis Blanchard /* extra exceptions */ 115bb3a8a17SHollis Blanchard case SPRN_IVOR32: 1168e5b26b5SAlexander Graf vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; 117bb3a8a17SHollis Blanchard break; 118bb3a8a17SHollis Blanchard case SPRN_IVOR33: 1198e5b26b5SAlexander Graf vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val; 120bb3a8a17SHollis Blanchard break; 121bb3a8a17SHollis Blanchard case SPRN_IVOR34: 1228e5b26b5SAlexander Graf vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val; 123bb3a8a17SHollis Blanchard break; 124bb3a8a17SHollis Blanchard case SPRN_IVOR35: 1258e5b26b5SAlexander Graf vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; 126bb3a8a17SHollis Blanchard break; 127bb3a8a17SHollis Blanchard 128bc8080cbSHollis Blanchard default: 129bc8080cbSHollis Blanchard emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs); 130bc8080cbSHollis Blanchard } 131bc8080cbSHollis Blanchard 132bc8080cbSHollis Blanchard return emulated; 133bc8080cbSHollis Blanchard } 134bc8080cbSHollis Blanchard 135bc8080cbSHollis Blanchard int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 136bc8080cbSHollis Blanchard { 137bc8080cbSHollis Blanchard struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 138bc8080cbSHollis Blanchard int emulated = EMULATE_DONE; 139bc8080cbSHollis Blanchard 140bc8080cbSHollis Blanchard switch (sprn) { 141bc8080cbSHollis Blanchard case SPRN_PID: 1428e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break; 143bc8080cbSHollis Blanchard case SPRN_PID1: 1448e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break; 145bc8080cbSHollis Blanchard case SPRN_PID2: 1468e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break; 147bc8080cbSHollis Blanchard case SPRN_MAS0: 1488e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas0); break; 149bc8080cbSHollis Blanchard case SPRN_MAS1: 1508e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas1); break; 151bc8080cbSHollis Blanchard case SPRN_MAS2: 1528e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas2); break; 153bc8080cbSHollis Blanchard case SPRN_MAS3: 1548e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas3); break; 155bc8080cbSHollis Blanchard case SPRN_MAS4: 1568e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas4); break; 157bc8080cbSHollis Blanchard case SPRN_MAS6: 1588e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas6); break; 159bc8080cbSHollis Blanchard case SPRN_MAS7: 1608e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->mas7); break; 161bc8080cbSHollis Blanchard 162bc8080cbSHollis Blanchard case SPRN_TLB0CFG: 1638e5b26b5SAlexander Graf { 1648e5b26b5SAlexander Graf ulong tmp = SPRN_TLB0CFG; 1658e5b26b5SAlexander Graf 1668e5b26b5SAlexander Graf tmp &= ~0xfffUL; 1678e5b26b5SAlexander Graf tmp |= vcpu_e500->guest_tlb_size[0]; 1688e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, tmp); 169bc8080cbSHollis Blanchard break; 1708e5b26b5SAlexander Graf } 171bc8080cbSHollis Blanchard 172bc8080cbSHollis Blanchard case SPRN_TLB1CFG: 1738e5b26b5SAlexander Graf { 1748e5b26b5SAlexander Graf ulong tmp = SPRN_TLB1CFG; 1758e5b26b5SAlexander Graf 1768e5b26b5SAlexander Graf tmp &= ~0xfffUL; 1778e5b26b5SAlexander Graf tmp |= vcpu_e500->guest_tlb_size[1]; 1788e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, tmp); 179bc8080cbSHollis Blanchard break; 1808e5b26b5SAlexander Graf } 181bc8080cbSHollis Blanchard 182bc8080cbSHollis Blanchard case SPRN_L1CSR1: 1838e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break; 184bc8080cbSHollis Blanchard case SPRN_HID0: 1858e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break; 186bc8080cbSHollis Blanchard case SPRN_HID1: 1878e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break; 188bc8080cbSHollis Blanchard 189b0a1835dSLiu Yu case SPRN_MMUCSR0: 1908e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, 0); break; 191b0a1835dSLiu Yu 19206579dd9SLiu Yu case SPRN_MMUCFG: 1938e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, mfspr(SPRN_MMUCFG)); break; 19406579dd9SLiu Yu 195bb3a8a17SHollis Blanchard /* extra exceptions */ 196bb3a8a17SHollis Blanchard case SPRN_IVOR32: 1978e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]); 198bb3a8a17SHollis Blanchard break; 199bb3a8a17SHollis Blanchard case SPRN_IVOR33: 2008e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]); 201bb3a8a17SHollis Blanchard break; 202bb3a8a17SHollis Blanchard case SPRN_IVOR34: 2038e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]); 204bb3a8a17SHollis Blanchard break; 205bb3a8a17SHollis Blanchard case SPRN_IVOR35: 2068e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]); 207bb3a8a17SHollis Blanchard break; 208bc8080cbSHollis Blanchard default: 209bc8080cbSHollis Blanchard emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt); 210bc8080cbSHollis Blanchard } 211bc8080cbSHollis Blanchard 212bc8080cbSHollis Blanchard return emulated; 213bc8080cbSHollis Blanchard } 214bc8080cbSHollis Blanchard 215