machine.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. #include "hw/hw.h"
  2. #include "hw/boards.h"
  3. #include "cpu.h"
  4. static void save_tc(QEMUFile *f, TCState *tc)
  5. {
  6. int i;
  7. /* Save active TC */
  8. for(i = 0; i < 32; i++)
  9. qemu_put_betls(f, &tc->gpr[i]);
  10. qemu_put_betls(f, &tc->PC);
  11. for(i = 0; i < MIPS_DSP_ACC; i++)
  12. qemu_put_betls(f, &tc->HI[i]);
  13. for(i = 0; i < MIPS_DSP_ACC; i++)
  14. qemu_put_betls(f, &tc->LO[i]);
  15. for(i = 0; i < MIPS_DSP_ACC; i++)
  16. qemu_put_betls(f, &tc->ACX[i]);
  17. qemu_put_betls(f, &tc->DSPControl);
  18. qemu_put_sbe32s(f, &tc->CP0_TCStatus);
  19. qemu_put_sbe32s(f, &tc->CP0_TCBind);
  20. qemu_put_betls(f, &tc->CP0_TCHalt);
  21. qemu_put_betls(f, &tc->CP0_TCContext);
  22. qemu_put_betls(f, &tc->CP0_TCSchedule);
  23. qemu_put_betls(f, &tc->CP0_TCScheFBack);
  24. qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
  25. }
  26. static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
  27. {
  28. int i;
  29. for(i = 0; i < 32; i++)
  30. qemu_put_be64s(f, &fpu->fpr[i].d);
  31. qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
  32. qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
  33. qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
  34. qemu_put_be32s(f, &fpu->fcr0);
  35. qemu_put_be32s(f, &fpu->fcr31);
  36. }
  37. void cpu_save(QEMUFile *f, void *opaque)
  38. {
  39. CPUMIPSState *env = opaque;
  40. int i;
  41. /* Save active TC */
  42. save_tc(f, &env->active_tc);
  43. /* Save active FPU */
  44. save_fpu(f, &env->active_fpu);
  45. /* Save MVP */
  46. qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
  47. qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
  48. qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
  49. /* Save TLB */
  50. qemu_put_be32s(f, &env->tlb->nb_tlb);
  51. qemu_put_be32s(f, &env->tlb->tlb_in_use);
  52. for(i = 0; i < MIPS_TLB_MAX; i++) {
  53. uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].G << 10) |
  54. (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
  55. (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
  56. (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
  57. (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
  58. (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
  59. (env->tlb->mmu.r4k.tlb[i].D1 << 0));
  60. uint8_t asid;
  61. qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
  62. qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
  63. asid = env->tlb->mmu.r4k.tlb[i].ASID;
  64. qemu_put_8s(f, &asid);
  65. qemu_put_be16s(f, &flags);
  66. qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
  67. qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
  68. }
  69. /* Save CPU metastate */
  70. qemu_put_be32s(f, &env->current_tc);
  71. qemu_put_be32s(f, &env->current_fpu);
  72. qemu_put_sbe32s(f, &env->error_code);
  73. qemu_put_be32s(f, &env->hflags);
  74. qemu_put_betls(f, &env->btarget);
  75. i = env->bcond;
  76. qemu_put_sbe32s(f, &i);
  77. /* Save remaining CP1 registers */
  78. qemu_put_sbe32s(f, &env->CP0_Index);
  79. qemu_put_sbe32s(f, &env->CP0_Random);
  80. qemu_put_sbe32s(f, &env->CP0_VPEControl);
  81. qemu_put_sbe32s(f, &env->CP0_VPEConf0);
  82. qemu_put_sbe32s(f, &env->CP0_VPEConf1);
  83. qemu_put_betls(f, &env->CP0_YQMask);
  84. qemu_put_betls(f, &env->CP0_VPESchedule);
  85. qemu_put_betls(f, &env->CP0_VPEScheFBack);
  86. qemu_put_sbe32s(f, &env->CP0_VPEOpt);
  87. qemu_put_betls(f, &env->CP0_EntryLo0);
  88. qemu_put_betls(f, &env->CP0_EntryLo1);
  89. qemu_put_betls(f, &env->CP0_Context);
  90. qemu_put_sbe32s(f, &env->CP0_PageMask);
  91. qemu_put_sbe32s(f, &env->CP0_PageGrain);
  92. qemu_put_sbe32s(f, &env->CP0_Wired);
  93. qemu_put_sbe32s(f, &env->CP0_SRSConf0);
  94. qemu_put_sbe32s(f, &env->CP0_SRSConf1);
  95. qemu_put_sbe32s(f, &env->CP0_SRSConf2);
  96. qemu_put_sbe32s(f, &env->CP0_SRSConf3);
  97. qemu_put_sbe32s(f, &env->CP0_SRSConf4);
  98. qemu_put_sbe32s(f, &env->CP0_HWREna);
  99. qemu_put_betls(f, &env->CP0_BadVAddr);
  100. qemu_put_sbe32s(f, &env->CP0_Count);
  101. qemu_put_betls(f, &env->CP0_EntryHi);
  102. qemu_put_sbe32s(f, &env->CP0_Compare);
  103. qemu_put_sbe32s(f, &env->CP0_Status);
  104. qemu_put_sbe32s(f, &env->CP0_IntCtl);
  105. qemu_put_sbe32s(f, &env->CP0_SRSCtl);
  106. qemu_put_sbe32s(f, &env->CP0_SRSMap);
  107. qemu_put_sbe32s(f, &env->CP0_Cause);
  108. qemu_put_betls(f, &env->CP0_EPC);
  109. qemu_put_sbe32s(f, &env->CP0_PRid);
  110. qemu_put_sbe32s(f, &env->CP0_EBase);
  111. qemu_put_sbe32s(f, &env->CP0_Config0);
  112. qemu_put_sbe32s(f, &env->CP0_Config1);
  113. qemu_put_sbe32s(f, &env->CP0_Config2);
  114. qemu_put_sbe32s(f, &env->CP0_Config3);
  115. qemu_put_sbe32s(f, &env->CP0_Config6);
  116. qemu_put_sbe32s(f, &env->CP0_Config7);
  117. qemu_put_betls(f, &env->lladdr);
  118. for(i = 0; i < 8; i++)
  119. qemu_put_betls(f, &env->CP0_WatchLo[i]);
  120. for(i = 0; i < 8; i++)
  121. qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
  122. qemu_put_betls(f, &env->CP0_XContext);
  123. qemu_put_sbe32s(f, &env->CP0_Framemask);
  124. qemu_put_sbe32s(f, &env->CP0_Debug);
  125. qemu_put_betls(f, &env->CP0_DEPC);
  126. qemu_put_sbe32s(f, &env->CP0_Performance0);
  127. qemu_put_sbe32s(f, &env->CP0_TagLo);
  128. qemu_put_sbe32s(f, &env->CP0_DataLo);
  129. qemu_put_sbe32s(f, &env->CP0_TagHi);
  130. qemu_put_sbe32s(f, &env->CP0_DataHi);
  131. qemu_put_betls(f, &env->CP0_ErrorEPC);
  132. qemu_put_sbe32s(f, &env->CP0_DESAVE);
  133. /* Save inactive TC state */
  134. for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
  135. save_tc(f, &env->tcs[i]);
  136. for (i = 0; i < MIPS_FPU_MAX; i++)
  137. save_fpu(f, &env->fpus[i]);
  138. }
  139. static void load_tc(QEMUFile *f, TCState *tc)
  140. {
  141. int i;
  142. /* Save active TC */
  143. for(i = 0; i < 32; i++)
  144. qemu_get_betls(f, &tc->gpr[i]);
  145. qemu_get_betls(f, &tc->PC);
  146. for(i = 0; i < MIPS_DSP_ACC; i++)
  147. qemu_get_betls(f, &tc->HI[i]);
  148. for(i = 0; i < MIPS_DSP_ACC; i++)
  149. qemu_get_betls(f, &tc->LO[i]);
  150. for(i = 0; i < MIPS_DSP_ACC; i++)
  151. qemu_get_betls(f, &tc->ACX[i]);
  152. qemu_get_betls(f, &tc->DSPControl);
  153. qemu_get_sbe32s(f, &tc->CP0_TCStatus);
  154. qemu_get_sbe32s(f, &tc->CP0_TCBind);
  155. qemu_get_betls(f, &tc->CP0_TCHalt);
  156. qemu_get_betls(f, &tc->CP0_TCContext);
  157. qemu_get_betls(f, &tc->CP0_TCSchedule);
  158. qemu_get_betls(f, &tc->CP0_TCScheFBack);
  159. qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
  160. }
  161. static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
  162. {
  163. int i;
  164. for(i = 0; i < 32; i++)
  165. qemu_get_be64s(f, &fpu->fpr[i].d);
  166. qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
  167. qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
  168. qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
  169. qemu_get_be32s(f, &fpu->fcr0);
  170. qemu_get_be32s(f, &fpu->fcr31);
  171. }
  172. int cpu_load(QEMUFile *f, void *opaque, int version_id)
  173. {
  174. CPUMIPSState *env = opaque;
  175. int i;
  176. if (version_id != 3)
  177. return -EINVAL;
  178. /* Load active TC */
  179. load_tc(f, &env->active_tc);
  180. /* Load active FPU */
  181. load_fpu(f, &env->active_fpu);
  182. /* Load MVP */
  183. qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
  184. qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
  185. qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
  186. /* Load TLB */
  187. qemu_get_be32s(f, &env->tlb->nb_tlb);
  188. qemu_get_be32s(f, &env->tlb->tlb_in_use);
  189. for(i = 0; i < MIPS_TLB_MAX; i++) {
  190. uint16_t flags;
  191. uint8_t asid;
  192. qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
  193. qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
  194. qemu_get_8s(f, &asid);
  195. env->tlb->mmu.r4k.tlb[i].ASID = asid;
  196. qemu_get_be16s(f, &flags);
  197. env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
  198. env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
  199. env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
  200. env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
  201. env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
  202. env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
  203. env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
  204. qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
  205. qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
  206. }
  207. /* Load CPU metastate */
  208. qemu_get_be32s(f, &env->current_tc);
  209. qemu_get_be32s(f, &env->current_fpu);
  210. qemu_get_sbe32s(f, &env->error_code);
  211. qemu_get_be32s(f, &env->hflags);
  212. qemu_get_betls(f, &env->btarget);
  213. qemu_get_sbe32s(f, &i);
  214. env->bcond = i;
  215. /* Load remaining CP1 registers */
  216. qemu_get_sbe32s(f, &env->CP0_Index);
  217. qemu_get_sbe32s(f, &env->CP0_Random);
  218. qemu_get_sbe32s(f, &env->CP0_VPEControl);
  219. qemu_get_sbe32s(f, &env->CP0_VPEConf0);
  220. qemu_get_sbe32s(f, &env->CP0_VPEConf1);
  221. qemu_get_betls(f, &env->CP0_YQMask);
  222. qemu_get_betls(f, &env->CP0_VPESchedule);
  223. qemu_get_betls(f, &env->CP0_VPEScheFBack);
  224. qemu_get_sbe32s(f, &env->CP0_VPEOpt);
  225. qemu_get_betls(f, &env->CP0_EntryLo0);
  226. qemu_get_betls(f, &env->CP0_EntryLo1);
  227. qemu_get_betls(f, &env->CP0_Context);
  228. qemu_get_sbe32s(f, &env->CP0_PageMask);
  229. qemu_get_sbe32s(f, &env->CP0_PageGrain);
  230. qemu_get_sbe32s(f, &env->CP0_Wired);
  231. qemu_get_sbe32s(f, &env->CP0_SRSConf0);
  232. qemu_get_sbe32s(f, &env->CP0_SRSConf1);
  233. qemu_get_sbe32s(f, &env->CP0_SRSConf2);
  234. qemu_get_sbe32s(f, &env->CP0_SRSConf3);
  235. qemu_get_sbe32s(f, &env->CP0_SRSConf4);
  236. qemu_get_sbe32s(f, &env->CP0_HWREna);
  237. qemu_get_betls(f, &env->CP0_BadVAddr);
  238. qemu_get_sbe32s(f, &env->CP0_Count);
  239. qemu_get_betls(f, &env->CP0_EntryHi);
  240. qemu_get_sbe32s(f, &env->CP0_Compare);
  241. qemu_get_sbe32s(f, &env->CP0_Status);
  242. qemu_get_sbe32s(f, &env->CP0_IntCtl);
  243. qemu_get_sbe32s(f, &env->CP0_SRSCtl);
  244. qemu_get_sbe32s(f, &env->CP0_SRSMap);
  245. qemu_get_sbe32s(f, &env->CP0_Cause);
  246. qemu_get_betls(f, &env->CP0_EPC);
  247. qemu_get_sbe32s(f, &env->CP0_PRid);
  248. qemu_get_sbe32s(f, &env->CP0_EBase);
  249. qemu_get_sbe32s(f, &env->CP0_Config0);
  250. qemu_get_sbe32s(f, &env->CP0_Config1);
  251. qemu_get_sbe32s(f, &env->CP0_Config2);
  252. qemu_get_sbe32s(f, &env->CP0_Config3);
  253. qemu_get_sbe32s(f, &env->CP0_Config6);
  254. qemu_get_sbe32s(f, &env->CP0_Config7);
  255. qemu_get_betls(f, &env->lladdr);
  256. for(i = 0; i < 8; i++)
  257. qemu_get_betls(f, &env->CP0_WatchLo[i]);
  258. for(i = 0; i < 8; i++)
  259. qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
  260. qemu_get_betls(f, &env->CP0_XContext);
  261. qemu_get_sbe32s(f, &env->CP0_Framemask);
  262. qemu_get_sbe32s(f, &env->CP0_Debug);
  263. qemu_get_betls(f, &env->CP0_DEPC);
  264. qemu_get_sbe32s(f, &env->CP0_Performance0);
  265. qemu_get_sbe32s(f, &env->CP0_TagLo);
  266. qemu_get_sbe32s(f, &env->CP0_DataLo);
  267. qemu_get_sbe32s(f, &env->CP0_TagHi);
  268. qemu_get_sbe32s(f, &env->CP0_DataHi);
  269. qemu_get_betls(f, &env->CP0_ErrorEPC);
  270. qemu_get_sbe32s(f, &env->CP0_DESAVE);
  271. /* Load inactive TC state */
  272. for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
  273. load_tc(f, &env->tcs[i]);
  274. for (i = 0; i < MIPS_FPU_MAX; i++)
  275. load_fpu(f, &env->fpus[i]);
  276. /* XXX: ensure compatibility for halted bit ? */
  277. tlb_flush(env, 1);
  278. return 0;
  279. }