ARM: SMDKC110: Add audio devices on board
[safe/jmp/linux-2.6] / arch / powerpc / kvm / 44x_emulate.c
index 82489a7..65ea083 100644 (file)
 #include "booke.h"
 #include "44x_tlb.h"
 
-#define OP_RFI      19
-
-#define XOP_RFI     50
-#define XOP_MFMSR   83
-#define XOP_WRTEE   131
-#define XOP_MTMSR   146
-#define XOP_WRTEEI  163
 #define XOP_MFDCR   323
 #define XOP_MTDCR   451
 #define XOP_TLBSX   914
 #define XOP_ICCCI   966
 #define XOP_TLBWE   978
 
-static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
-{
-       vcpu->arch.pc = vcpu->arch.srr0;
-       kvmppc_set_msr(vcpu, vcpu->arch.srr1);
-}
-
 int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                            unsigned int inst, int *advance)
 {
@@ -59,48 +46,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
        int ws;
 
        switch (get_op(inst)) {
-       case OP_RFI:
-               switch (get_xop(inst)) {
-               case XOP_RFI:
-                       kvmppc_emul_rfi(vcpu);
-                       kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
-                       *advance = 0;
-                       break;
-
-               default:
-                       emulated = EMULATE_FAIL;
-                       break;
-               }
-               break;
-
        case 31:
                switch (get_xop(inst)) {
 
-               case XOP_MFMSR:
-                       rt = get_rt(inst);
-                       vcpu->arch.gpr[rt] = vcpu->arch.msr;
-                       kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
-                       break;
-
-               case XOP_MTMSR:
-                       rs = get_rs(inst);
-                       kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
-                       kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
-                       break;
-
-               case XOP_WRTEE:
-                       rs = get_rs(inst);
-                       vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
-                                                        | (vcpu->arch.gpr[rs] & MSR_EE);
-                       kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
-                       break;
-
-               case XOP_WRTEEI:
-                       vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
-                                                        | (inst & MSR_EE);
-                       kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
-                       break;
-
                case XOP_MFDCR:
                        dcrn = get_dcrn(inst);
                        rt = get_rt(inst);
@@ -117,13 +65,14 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                         */
                        switch (dcrn) {
                        case DCRN_CPR0_CONFIG_ADDR:
-                               vcpu->arch.gpr[rt] = vcpu->arch.cpr0_cfgaddr;
+                               kvmppc_set_gpr(vcpu, rt, vcpu->arch.cpr0_cfgaddr);
                                break;
                        case DCRN_CPR0_CONFIG_DATA:
                                local_irq_disable();
                                mtdcr(DCRN_CPR0_CONFIG_ADDR,
                                          vcpu->arch.cpr0_cfgaddr);
-                               vcpu->arch.gpr[rt] = mfdcr(DCRN_CPR0_CONFIG_DATA);
+                               kvmppc_set_gpr(vcpu, rt,
+                                              mfdcr(DCRN_CPR0_CONFIG_DATA));
                                local_irq_enable();
                                break;
                        default:
@@ -145,11 +94,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        /* emulate some access in kernel */
                        switch (dcrn) {
                        case DCRN_CPR0_CONFIG_ADDR:
-                               vcpu->arch.cpr0_cfgaddr = vcpu->arch.gpr[rs];
+                               vcpu->arch.cpr0_cfgaddr = kvmppc_get_gpr(vcpu, rs);
                                break;
                        default:
                                run->dcr.dcrn = dcrn;
-                               run->dcr.data = vcpu->arch.gpr[rs];
+                               run->dcr.data = kvmppc_get_gpr(vcpu, rs);
                                run->dcr.is_write = 1;
                                vcpu->arch.dcr_needed = 1;
                                kvmppc_account_exit(vcpu, DCR_EXITS);
@@ -186,186 +135,51 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                emulated = EMULATE_FAIL;
        }
 
+       if (emulated == EMULATE_FAIL)
+               emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
+
        return emulated;
 }
 
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 {
+       int emulated = EMULATE_DONE;
+
        switch (sprn) {
-       case SPRN_MMUCR:
-               vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
        case SPRN_PID:
-               kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+               kvmppc_set_pid(vcpu, kvmppc_get_gpr(vcpu, rs)); break;
+       case SPRN_MMUCR:
+               vcpu->arch.mmucr = kvmppc_get_gpr(vcpu, rs); break;
        case SPRN_CCR0:
-               vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
+               vcpu->arch.ccr0 = kvmppc_get_gpr(vcpu, rs); break;
        case SPRN_CCR1:
-               vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
-       case SPRN_DEAR:
-               vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
-       case SPRN_ESR:
-               vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
-       case SPRN_DBCR0:
-               vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
-       case SPRN_DBCR1:
-               vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
-       case SPRN_TSR:
-               vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
-       case SPRN_TCR:
-               vcpu->arch.tcr = vcpu->arch.gpr[rs];
-               kvmppc_emulate_dec(vcpu);
-               break;
-
-       /* Note: SPRG4-7 are user-readable. These values are
-        * loaded into the real SPRGs when resuming the
-        * guest. */
-       case SPRN_SPRG4:
-               vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
-       case SPRN_SPRG5:
-               vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
-       case SPRN_SPRG6:
-               vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
-       case SPRN_SPRG7:
-               vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
-
-       case SPRN_IVPR:
-               vcpu->arch.ivpr = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR0:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR1:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR2:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR3:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR4:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR5:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR6:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR7:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR8:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR9:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR10:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR11:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR12:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR13:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR14:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
-               break;
-       case SPRN_IVOR15:
-               vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
-               break;
-
+               vcpu->arch.ccr1 = kvmppc_get_gpr(vcpu, rs); break;
        default:
-               return EMULATE_FAIL;
+               emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
        }
 
        kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
-       return EMULATE_DONE;
+       return emulated;
 }
 
 int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 {
+       int emulated = EMULATE_DONE;
+
        switch (sprn) {
-       /* 440 */
+       case SPRN_PID:
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.pid); break;
        case SPRN_MMUCR:
-               vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucr); break;
        case SPRN_CCR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr0); break;
        case SPRN_CCR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
-
-       /* Book E */
-       case SPRN_PID:
-               vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
-       case SPRN_IVPR:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
-       case SPRN_DEAR:
-               vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
-       case SPRN_ESR:
-               vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
-       case SPRN_DBCR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
-       case SPRN_DBCR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
-
-       case SPRN_IVOR0:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
-               break;
-       case SPRN_IVOR1:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
-               break;
-       case SPRN_IVOR2:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
-               break;
-       case SPRN_IVOR3:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
-               break;
-       case SPRN_IVOR4:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
-               break;
-       case SPRN_IVOR5:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
-               break;
-       case SPRN_IVOR6:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
-               break;
-       case SPRN_IVOR7:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
-               break;
-       case SPRN_IVOR8:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
-               break;
-       case SPRN_IVOR9:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
-               break;
-       case SPRN_IVOR10:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
-               break;
-       case SPRN_IVOR11:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
-               break;
-       case SPRN_IVOR12:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
-               break;
-       case SPRN_IVOR13:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
-               break;
-       case SPRN_IVOR14:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
-               break;
-       case SPRN_IVOR15:
-               vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
-               break;
-
+               kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr1); break;
        default:
-               return EMULATE_FAIL;
+               emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
        }
 
        kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
-       return EMULATE_DONE;
+       return emulated;
 }