2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
4 * Author: Yu Liu, <yu.liu@freescale.com>
7 * This file is derived from arch/powerpc/kvm/44x_emulate.c,
8 * by Hollis Blanchard <hollisb@us.ibm.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
15 #include <asm/kvm_ppc.h>
16 #include <asm/disassemble.h>
17 #include <asm/kvm_e500.h>
22 #define XOP_TLBIVAX 786
27 int kvmppc_core_emulate_op(struct kvm_run
*run
, struct kvm_vcpu
*vcpu
,
28 unsigned int inst
, int *advance
)
30 int emulated
= EMULATE_DONE
;
34 switch (get_op(inst
)) {
36 switch (get_xop(inst
)) {
39 emulated
= kvmppc_e500_emul_tlbre(vcpu
);
43 emulated
= kvmppc_e500_emul_tlbwe(vcpu
);
48 emulated
= kvmppc_e500_emul_tlbsx(vcpu
,rb
);
54 emulated
= kvmppc_e500_emul_tlbivax(vcpu
, ra
, rb
);
58 emulated
= EMULATE_FAIL
;
64 emulated
= EMULATE_FAIL
;
67 if (emulated
== EMULATE_FAIL
)
68 emulated
= kvmppc_booke_emulate_op(run
, vcpu
, inst
, advance
);
73 int kvmppc_core_emulate_mtspr(struct kvm_vcpu
*vcpu
, int sprn
, int rs
)
75 struct kvmppc_vcpu_e500
*vcpu_e500
= to_e500(vcpu
);
76 int emulated
= EMULATE_DONE
;
80 vcpu_e500
->pid
[0] = vcpu
->arch
.shadow_pid
=
81 vcpu
->arch
.pid
= vcpu
->arch
.gpr
[rs
];
84 vcpu_e500
->pid
[1] = vcpu
->arch
.gpr
[rs
]; break;
86 vcpu_e500
->pid
[2] = vcpu
->arch
.gpr
[rs
]; break;
88 vcpu_e500
->mas0
= vcpu
->arch
.gpr
[rs
]; break;
90 vcpu_e500
->mas1
= vcpu
->arch
.gpr
[rs
]; break;
92 vcpu_e500
->mas2
= vcpu
->arch
.gpr
[rs
]; break;
94 vcpu_e500
->mas3
= vcpu
->arch
.gpr
[rs
]; break;
96 vcpu_e500
->mas4
= vcpu
->arch
.gpr
[rs
]; break;
98 vcpu_e500
->mas6
= vcpu
->arch
.gpr
[rs
]; break;
100 vcpu_e500
->mas7
= vcpu
->arch
.gpr
[rs
]; break;
102 vcpu_e500
->l1csr1
= vcpu
->arch
.gpr
[rs
]; break;
104 vcpu_e500
->hid0
= vcpu
->arch
.gpr
[rs
]; break;
106 vcpu_e500
->hid1
= vcpu
->arch
.gpr
[rs
]; break;
109 emulated
= kvmppc_e500_emul_mt_mmucsr0(vcpu_e500
,
113 /* extra exceptions */
115 vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_UNAVAIL
] = vcpu
->arch
.gpr
[rs
];
118 vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_FP_DATA
] = vcpu
->arch
.gpr
[rs
];
121 vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_FP_ROUND
] = vcpu
->arch
.gpr
[rs
];
124 vcpu
->arch
.ivor
[BOOKE_IRQPRIO_PERFORMANCE_MONITOR
] = vcpu
->arch
.gpr
[rs
];
128 emulated
= kvmppc_booke_emulate_mtspr(vcpu
, sprn
, rs
);
134 int kvmppc_core_emulate_mfspr(struct kvm_vcpu
*vcpu
, int sprn
, int rt
)
136 struct kvmppc_vcpu_e500
*vcpu_e500
= to_e500(vcpu
);
137 int emulated
= EMULATE_DONE
;
141 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->pid
[0]; break;
143 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->pid
[1]; break;
145 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->pid
[2]; break;
147 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas0
; break;
149 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas1
; break;
151 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas2
; break;
153 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas3
; break;
155 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas4
; break;
157 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas6
; break;
159 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->mas7
; break;
162 vcpu
->arch
.gpr
[rt
] = mfspr(SPRN_TLB0CFG
);
163 vcpu
->arch
.gpr
[rt
] &= ~0xfffUL
;
164 vcpu
->arch
.gpr
[rt
] |= vcpu_e500
->guest_tlb_size
[0];
168 vcpu
->arch
.gpr
[rt
] = mfspr(SPRN_TLB1CFG
);
169 vcpu
->arch
.gpr
[rt
] &= ~0xfffUL
;
170 vcpu
->arch
.gpr
[rt
] |= vcpu_e500
->guest_tlb_size
[1];
174 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->l1csr1
; break;
176 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->hid0
; break;
178 vcpu
->arch
.gpr
[rt
] = vcpu_e500
->hid1
; break;
181 vcpu
->arch
.gpr
[rt
] = 0; break;
184 vcpu
->arch
.gpr
[rt
] = mfspr(SPRN_MMUCFG
); break;
186 /* extra exceptions */
188 vcpu
->arch
.gpr
[rt
] = vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_UNAVAIL
];
191 vcpu
->arch
.gpr
[rt
] = vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_FP_DATA
];
194 vcpu
->arch
.gpr
[rt
] = vcpu
->arch
.ivor
[BOOKE_IRQPRIO_SPE_FP_ROUND
];
197 vcpu
->arch
.gpr
[rt
] = vcpu
->arch
.ivor
[BOOKE_IRQPRIO_PERFORMANCE_MONITOR
];
200 emulated
= kvmppc_booke_emulate_mfspr(vcpu
, sprn
, rt
);