e500_emulate.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /*
  2. * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
  3. *
  4. * Author: Yu Liu, <yu.liu@freescale.com>
  5. *
  6. * Description:
  7. * This file is derived from arch/powerpc/kvm/44x_emulate.c,
  8. * by Hollis Blanchard <hollisb@us.ibm.com>.
  9. *
  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.
  13. */
  14. #include <asm/kvm_ppc.h>
  15. #include <asm/disassemble.h>
  16. #include <asm/dbell.h>
  17. #include "booke.h"
  18. #include "e500.h"
  19. #define XOP_DCBTLS 166
  20. #define XOP_MSGSND 206
  21. #define XOP_MSGCLR 238
  22. #define XOP_TLBIVAX 786
  23. #define XOP_TLBSX 914
  24. #define XOP_TLBRE 946
  25. #define XOP_TLBWE 978
  26. #define XOP_TLBILX 18
  27. #define XOP_EHPRIV 270
  28. #ifdef CONFIG_KVM_E500MC
  29. static int dbell2prio(ulong param)
  30. {
  31. int msg = param & PPC_DBELL_TYPE_MASK;
  32. int prio = -1;
  33. switch (msg) {
  34. case PPC_DBELL_TYPE(PPC_DBELL):
  35. prio = BOOKE_IRQPRIO_DBELL;
  36. break;
  37. case PPC_DBELL_TYPE(PPC_DBELL_CRIT):
  38. prio = BOOKE_IRQPRIO_DBELL_CRIT;
  39. break;
  40. default:
  41. break;
  42. }
  43. return prio;
  44. }
  45. static int kvmppc_e500_emul_msgclr(struct kvm_vcpu *vcpu, int rb)
  46. {
  47. ulong param = vcpu->arch.gpr[rb];
  48. int prio = dbell2prio(param);
  49. if (prio < 0)
  50. return EMULATE_FAIL;
  51. clear_bit(prio, &vcpu->arch.pending_exceptions);
  52. return EMULATE_DONE;
  53. }
  54. static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
  55. {
  56. ulong param = vcpu->arch.gpr[rb];
  57. int prio = dbell2prio(rb);
  58. int pir = param & PPC_DBELL_PIR_MASK;
  59. int i;
  60. struct kvm_vcpu *cvcpu;
  61. if (prio < 0)
  62. return EMULATE_FAIL;
  63. kvm_for_each_vcpu(i, cvcpu, vcpu->kvm) {
  64. int cpir = cvcpu->arch.shared->pir;
  65. if ((param & PPC_DBELL_MSG_BRDCAST) || (cpir == pir)) {
  66. set_bit(prio, &cvcpu->arch.pending_exceptions);
  67. kvm_vcpu_kick(cvcpu);
  68. }
  69. }
  70. return EMULATE_DONE;
  71. }
  72. #endif
  73. static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
  74. unsigned int inst, int *advance)
  75. {
  76. int emulated = EMULATE_DONE;
  77. switch (get_oc(inst)) {
  78. case EHPRIV_OC_DEBUG:
  79. run->exit_reason = KVM_EXIT_DEBUG;
  80. run->debug.arch.address = vcpu->arch.pc;
  81. run->debug.arch.status = 0;
  82. kvmppc_account_exit(vcpu, DEBUG_EXITS);
  83. emulated = EMULATE_EXIT_USER;
  84. *advance = 0;
  85. break;
  86. default:
  87. emulated = EMULATE_FAIL;
  88. }
  89. return emulated;
  90. }
  91. static int kvmppc_e500_emul_dcbtls(struct kvm_vcpu *vcpu)
  92. {
  93. struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
  94. /* Always fail to lock the cache */
  95. vcpu_e500->l1csr0 |= L1CSR0_CUL;
  96. return EMULATE_DONE;
  97. }
  98. int kvmppc_core_emulate_op_e500(struct kvm_run *run, struct kvm_vcpu *vcpu,
  99. unsigned int inst, int *advance)
  100. {
  101. int emulated = EMULATE_DONE;
  102. int ra = get_ra(inst);
  103. int rb = get_rb(inst);
  104. int rt = get_rt(inst);
  105. gva_t ea;
  106. switch (get_op(inst)) {
  107. case 31:
  108. switch (get_xop(inst)) {
  109. case XOP_DCBTLS:
  110. emulated = kvmppc_e500_emul_dcbtls(vcpu);
  111. break;
  112. #ifdef CONFIG_KVM_E500MC
  113. case XOP_MSGSND:
  114. emulated = kvmppc_e500_emul_msgsnd(vcpu, rb);
  115. break;
  116. case XOP_MSGCLR:
  117. emulated = kvmppc_e500_emul_msgclr(vcpu, rb);
  118. break;
  119. #endif
  120. case XOP_TLBRE:
  121. emulated = kvmppc_e500_emul_tlbre(vcpu);
  122. break;
  123. case XOP_TLBWE:
  124. emulated = kvmppc_e500_emul_tlbwe(vcpu);
  125. break;
  126. case XOP_TLBSX:
  127. ea = kvmppc_get_ea_indexed(vcpu, ra, rb);
  128. emulated = kvmppc_e500_emul_tlbsx(vcpu, ea);
  129. break;
  130. case XOP_TLBILX: {
  131. int type = rt & 0x3;
  132. ea = kvmppc_get_ea_indexed(vcpu, ra, rb);
  133. emulated = kvmppc_e500_emul_tlbilx(vcpu, type, ea);
  134. break;
  135. }
  136. case XOP_TLBIVAX:
  137. ea = kvmppc_get_ea_indexed(vcpu, ra, rb);
  138. emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
  139. break;
  140. case XOP_EHPRIV:
  141. emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
  142. advance);
  143. break;
  144. default:
  145. emulated = EMULATE_FAIL;
  146. }
  147. break;
  148. default:
  149. emulated = EMULATE_FAIL;
  150. }
  151. if (emulated == EMULATE_FAIL)
  152. emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
  153. return emulated;
  154. }
  155. int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
  156. {
  157. struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
  158. int emulated = EMULATE_DONE;
  159. switch (sprn) {
  160. #ifndef CONFIG_KVM_BOOKE_HV
  161. case SPRN_PID:
  162. kvmppc_set_pid(vcpu, spr_val);
  163. break;
  164. case SPRN_PID1:
  165. if (spr_val != 0)
  166. return EMULATE_FAIL;
  167. vcpu_e500->pid[1] = spr_val;
  168. break;
  169. case SPRN_PID2:
  170. if (spr_val != 0)
  171. return EMULATE_FAIL;
  172. vcpu_e500->pid[2] = spr_val;
  173. break;
  174. case SPRN_MAS0:
  175. vcpu->arch.shared->mas0 = spr_val;
  176. break;
  177. case SPRN_MAS1:
  178. vcpu->arch.shared->mas1 = spr_val;
  179. break;
  180. case SPRN_MAS2:
  181. vcpu->arch.shared->mas2 = spr_val;
  182. break;
  183. case SPRN_MAS3:
  184. vcpu->arch.shared->mas7_3 &= ~(u64)0xffffffff;
  185. vcpu->arch.shared->mas7_3 |= spr_val;
  186. break;
  187. case SPRN_MAS4:
  188. vcpu->arch.shared->mas4 = spr_val;
  189. break;
  190. case SPRN_MAS6:
  191. vcpu->arch.shared->mas6 = spr_val;
  192. break;
  193. case SPRN_MAS7:
  194. vcpu->arch.shared->mas7_3 &= (u64)0xffffffff;
  195. vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32;
  196. break;
  197. #endif
  198. case SPRN_L1CSR0:
  199. vcpu_e500->l1csr0 = spr_val;
  200. vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
  201. break;
  202. case SPRN_L1CSR1:
  203. vcpu_e500->l1csr1 = spr_val;
  204. vcpu_e500->l1csr1 &= ~(L1CSR1_ICFI | L1CSR1_ICLFR);
  205. break;
  206. case SPRN_HID0:
  207. vcpu_e500->hid0 = spr_val;
  208. break;
  209. case SPRN_HID1:
  210. vcpu_e500->hid1 = spr_val;
  211. break;
  212. case SPRN_MMUCSR0:
  213. emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
  214. spr_val);
  215. break;
  216. case SPRN_PWRMGTCR0:
  217. /*
  218. * Guest relies on host power management configurations
  219. * Treat the request as a general store
  220. */
  221. vcpu->arch.pwrmgtcr0 = spr_val;
  222. break;
  223. /* extra exceptions */
  224. #ifdef CONFIG_SPE_POSSIBLE
  225. case SPRN_IVOR32:
  226. vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val;
  227. break;
  228. case SPRN_IVOR33:
  229. vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val;
  230. break;
  231. case SPRN_IVOR34:
  232. vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val;
  233. break;
  234. #endif
  235. #ifdef CONFIG_ALTIVEC
  236. case SPRN_IVOR32:
  237. vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val;
  238. break;
  239. case SPRN_IVOR33:
  240. vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST] = spr_val;
  241. break;
  242. #endif
  243. case SPRN_IVOR35:
  244. vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
  245. break;
  246. #ifdef CONFIG_KVM_BOOKE_HV
  247. case SPRN_IVOR36:
  248. vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] = spr_val;
  249. break;
  250. case SPRN_IVOR37:
  251. vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] = spr_val;
  252. break;
  253. #endif
  254. default:
  255. emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val);
  256. }
  257. return emulated;
  258. }
  259. int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
  260. {
  261. struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
  262. int emulated = EMULATE_DONE;
  263. switch (sprn) {
  264. #ifndef CONFIG_KVM_BOOKE_HV
  265. case SPRN_PID:
  266. *spr_val = vcpu_e500->pid[0];
  267. break;
  268. case SPRN_PID1:
  269. *spr_val = vcpu_e500->pid[1];
  270. break;
  271. case SPRN_PID2:
  272. *spr_val = vcpu_e500->pid[2];
  273. break;
  274. case SPRN_MAS0:
  275. *spr_val = vcpu->arch.shared->mas0;
  276. break;
  277. case SPRN_MAS1:
  278. *spr_val = vcpu->arch.shared->mas1;
  279. break;
  280. case SPRN_MAS2:
  281. *spr_val = vcpu->arch.shared->mas2;
  282. break;
  283. case SPRN_MAS3:
  284. *spr_val = (u32)vcpu->arch.shared->mas7_3;
  285. break;
  286. case SPRN_MAS4:
  287. *spr_val = vcpu->arch.shared->mas4;
  288. break;
  289. case SPRN_MAS6:
  290. *spr_val = vcpu->arch.shared->mas6;
  291. break;
  292. case SPRN_MAS7:
  293. *spr_val = vcpu->arch.shared->mas7_3 >> 32;
  294. break;
  295. #endif
  296. case SPRN_DECAR:
  297. *spr_val = vcpu->arch.decar;
  298. break;
  299. case SPRN_TLB0CFG:
  300. *spr_val = vcpu->arch.tlbcfg[0];
  301. break;
  302. case SPRN_TLB1CFG:
  303. *spr_val = vcpu->arch.tlbcfg[1];
  304. break;
  305. case SPRN_TLB0PS:
  306. if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
  307. return EMULATE_FAIL;
  308. *spr_val = vcpu->arch.tlbps[0];
  309. break;
  310. case SPRN_TLB1PS:
  311. if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
  312. return EMULATE_FAIL;
  313. *spr_val = vcpu->arch.tlbps[1];
  314. break;
  315. case SPRN_L1CSR0:
  316. *spr_val = vcpu_e500->l1csr0;
  317. break;
  318. case SPRN_L1CSR1:
  319. *spr_val = vcpu_e500->l1csr1;
  320. break;
  321. case SPRN_HID0:
  322. *spr_val = vcpu_e500->hid0;
  323. break;
  324. case SPRN_HID1:
  325. *spr_val = vcpu_e500->hid1;
  326. break;
  327. case SPRN_SVR:
  328. *spr_val = vcpu_e500->svr;
  329. break;
  330. case SPRN_MMUCSR0:
  331. *spr_val = 0;
  332. break;
  333. case SPRN_MMUCFG:
  334. *spr_val = vcpu->arch.mmucfg;
  335. break;
  336. case SPRN_EPTCFG:
  337. if (!has_feature(vcpu, VCPU_FTR_MMU_V2))
  338. return EMULATE_FAIL;
  339. /*
  340. * Legacy Linux guests access EPTCFG register even if the E.PT
  341. * category is disabled in the VM. Give them a chance to live.
  342. */
  343. *spr_val = vcpu->arch.eptcfg;
  344. break;
  345. case SPRN_PWRMGTCR0:
  346. *spr_val = vcpu->arch.pwrmgtcr0;
  347. break;
  348. /* extra exceptions */
  349. #ifdef CONFIG_SPE_POSSIBLE
  350. case SPRN_IVOR32:
  351. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
  352. break;
  353. case SPRN_IVOR33:
  354. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
  355. break;
  356. case SPRN_IVOR34:
  357. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
  358. break;
  359. #endif
  360. #ifdef CONFIG_ALTIVEC
  361. case SPRN_IVOR32:
  362. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL];
  363. break;
  364. case SPRN_IVOR33:
  365. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST];
  366. break;
  367. #endif
  368. case SPRN_IVOR35:
  369. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
  370. break;
  371. #ifdef CONFIG_KVM_BOOKE_HV
  372. case SPRN_IVOR36:
  373. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL];
  374. break;
  375. case SPRN_IVOR37:
  376. *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT];
  377. break;
  378. #endif
  379. default:
  380. emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val);
  381. }
  382. return emulated;
  383. }