translate_init.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. * MIPS emulation for qemu: CPU initialisation routines.
  3. *
  4. * Copyright (c) 2004-2005 Jocelyn Mayer
  5. * Copyright (c) 2007 Herve Poussineau
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /* CPU / CPU family specific config register values. */
  21. /* Have config1, uncached coherency */
  22. #define MIPS_CONFIG0 \
  23. ((1 << CP0C0_M) | (0x2 << CP0C0_K0))
  24. /* Have config2, no coprocessor2 attached, no MDMX support attached,
  25. no performance counters, watch registers present,
  26. no code compression, EJTAG present, no FPU */
  27. #define MIPS_CONFIG1 \
  28. ((1 << CP0C1_M) | \
  29. (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
  30. (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \
  31. (0 << CP0C1_FP))
  32. /* Have config3, no tertiary/secondary caches implemented */
  33. #define MIPS_CONFIG2 \
  34. ((1 << CP0C2_M))
  35. /* No config4, no DSP ASE, no large physaddr (PABITS),
  36. no external interrupt controller, no vectored interrupts,
  37. no 1kb pages, no SmartMIPS ASE, no trace logic */
  38. #define MIPS_CONFIG3 \
  39. ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
  40. (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
  41. (0 << CP0C3_SM) | (0 << CP0C3_TL))
  42. /* MMU types, the first four entries have the same layout as the
  43. CP0C0_MT field. */
  44. enum mips_mmu_types {
  45. MMU_TYPE_NONE,
  46. MMU_TYPE_R4000,
  47. MMU_TYPE_RESERVED,
  48. MMU_TYPE_FMT,
  49. MMU_TYPE_R3000,
  50. MMU_TYPE_R6000,
  51. MMU_TYPE_R8000
  52. };
  53. struct mips_def_t {
  54. const char *name;
  55. int32_t CP0_PRid;
  56. int32_t CP0_Config0;
  57. int32_t CP0_Config1;
  58. int32_t CP0_Config2;
  59. int32_t CP0_Config3;
  60. int32_t CP0_Config6;
  61. int32_t CP0_Config7;
  62. target_ulong CP0_LLAddr_rw_bitmask;
  63. int CP0_LLAddr_shift;
  64. int32_t SYNCI_Step;
  65. int32_t CCRes;
  66. int32_t CP0_Status_rw_bitmask;
  67. int32_t CP0_TCStatus_rw_bitmask;
  68. int32_t CP0_SRSCtl;
  69. int32_t CP1_fcr0;
  70. int32_t SEGBITS;
  71. int32_t PABITS;
  72. int32_t CP0_SRSConf0_rw_bitmask;
  73. int32_t CP0_SRSConf0;
  74. int32_t CP0_SRSConf1_rw_bitmask;
  75. int32_t CP0_SRSConf1;
  76. int32_t CP0_SRSConf2_rw_bitmask;
  77. int32_t CP0_SRSConf2;
  78. int32_t CP0_SRSConf3_rw_bitmask;
  79. int32_t CP0_SRSConf3;
  80. int32_t CP0_SRSConf4_rw_bitmask;
  81. int32_t CP0_SRSConf4;
  82. int insn_flags;
  83. enum mips_mmu_types mmu_type;
  84. };
  85. /*****************************************************************************/
  86. /* MIPS CPU definitions */
  87. static const mips_def_t mips_defs[] =
  88. {
  89. {
  90. .name = "4Kc",
  91. .CP0_PRid = 0x00018000,
  92. .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT),
  93. .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
  94. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  95. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  96. (0 << CP0C1_CA),
  97. .CP0_Config2 = MIPS_CONFIG2,
  98. .CP0_Config3 = MIPS_CONFIG3,
  99. .CP0_LLAddr_rw_bitmask = 0,
  100. .CP0_LLAddr_shift = 4,
  101. .SYNCI_Step = 32,
  102. .CCRes = 2,
  103. .CP0_Status_rw_bitmask = 0x1278FF17,
  104. .SEGBITS = 32,
  105. .PABITS = 32,
  106. .insn_flags = CPU_MIPS32,
  107. .mmu_type = MMU_TYPE_R4000,
  108. },
  109. {
  110. .name = "4Km",
  111. .CP0_PRid = 0x00018300,
  112. /* Config1 implemented, fixed mapping MMU,
  113. no virtual icache, uncached coherency. */
  114. .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT),
  115. .CP0_Config1 = MIPS_CONFIG1 |
  116. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  117. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  118. (1 << CP0C1_CA),
  119. .CP0_Config2 = MIPS_CONFIG2,
  120. .CP0_Config3 = MIPS_CONFIG3,
  121. .CP0_LLAddr_rw_bitmask = 0,
  122. .CP0_LLAddr_shift = 4,
  123. .SYNCI_Step = 32,
  124. .CCRes = 2,
  125. .CP0_Status_rw_bitmask = 0x1258FF17,
  126. .SEGBITS = 32,
  127. .PABITS = 32,
  128. .insn_flags = CPU_MIPS32 | ASE_MIPS16,
  129. .mmu_type = MMU_TYPE_FMT,
  130. },
  131. {
  132. .name = "4KEcR1",
  133. .CP0_PRid = 0x00018400,
  134. .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT),
  135. .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
  136. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  137. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  138. (0 << CP0C1_CA),
  139. .CP0_Config2 = MIPS_CONFIG2,
  140. .CP0_Config3 = MIPS_CONFIG3,
  141. .CP0_LLAddr_rw_bitmask = 0,
  142. .CP0_LLAddr_shift = 4,
  143. .SYNCI_Step = 32,
  144. .CCRes = 2,
  145. .CP0_Status_rw_bitmask = 0x1278FF17,
  146. .SEGBITS = 32,
  147. .PABITS = 32,
  148. .insn_flags = CPU_MIPS32,
  149. .mmu_type = MMU_TYPE_R4000,
  150. },
  151. {
  152. .name = "4KEmR1",
  153. .CP0_PRid = 0x00018500,
  154. .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT),
  155. .CP0_Config1 = MIPS_CONFIG1 |
  156. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  157. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  158. (1 << CP0C1_CA),
  159. .CP0_Config2 = MIPS_CONFIG2,
  160. .CP0_Config3 = MIPS_CONFIG3,
  161. .CP0_LLAddr_rw_bitmask = 0,
  162. .CP0_LLAddr_shift = 4,
  163. .SYNCI_Step = 32,
  164. .CCRes = 2,
  165. .CP0_Status_rw_bitmask = 0x1258FF17,
  166. .SEGBITS = 32,
  167. .PABITS = 32,
  168. .insn_flags = CPU_MIPS32 | ASE_MIPS16,
  169. .mmu_type = MMU_TYPE_FMT,
  170. },
  171. {
  172. .name = "4KEc",
  173. .CP0_PRid = 0x00019000,
  174. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  175. (MMU_TYPE_R4000 << CP0C0_MT),
  176. .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
  177. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  178. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  179. (0 << CP0C1_CA),
  180. .CP0_Config2 = MIPS_CONFIG2,
  181. .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
  182. .CP0_LLAddr_rw_bitmask = 0,
  183. .CP0_LLAddr_shift = 4,
  184. .SYNCI_Step = 32,
  185. .CCRes = 2,
  186. .CP0_Status_rw_bitmask = 0x1278FF17,
  187. .SEGBITS = 32,
  188. .PABITS = 32,
  189. .insn_flags = CPU_MIPS32R2,
  190. .mmu_type = MMU_TYPE_R4000,
  191. },
  192. {
  193. .name = "4KEm",
  194. .CP0_PRid = 0x00019100,
  195. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  196. (MMU_TYPE_FMT << CP0C0_MT),
  197. .CP0_Config1 = MIPS_CONFIG1 |
  198. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  199. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  200. (1 << CP0C1_CA),
  201. .CP0_Config2 = MIPS_CONFIG2,
  202. .CP0_Config3 = MIPS_CONFIG3,
  203. .CP0_LLAddr_rw_bitmask = 0,
  204. .CP0_LLAddr_shift = 4,
  205. .SYNCI_Step = 32,
  206. .CCRes = 2,
  207. .CP0_Status_rw_bitmask = 0x1258FF17,
  208. .SEGBITS = 32,
  209. .PABITS = 32,
  210. .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
  211. .mmu_type = MMU_TYPE_FMT,
  212. },
  213. {
  214. .name = "24Kc",
  215. .CP0_PRid = 0x00019300,
  216. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  217. (MMU_TYPE_R4000 << CP0C0_MT),
  218. .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
  219. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  220. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  221. (1 << CP0C1_CA),
  222. .CP0_Config2 = MIPS_CONFIG2,
  223. .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
  224. .CP0_LLAddr_rw_bitmask = 0,
  225. .CP0_LLAddr_shift = 4,
  226. .SYNCI_Step = 32,
  227. .CCRes = 2,
  228. /* No DSP implemented. */
  229. .CP0_Status_rw_bitmask = 0x1278FF1F,
  230. .SEGBITS = 32,
  231. .PABITS = 32,
  232. .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
  233. .mmu_type = MMU_TYPE_R4000,
  234. },
  235. {
  236. .name = "24Kf",
  237. .CP0_PRid = 0x00019300,
  238. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  239. (MMU_TYPE_R4000 << CP0C0_MT),
  240. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
  241. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  242. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  243. (1 << CP0C1_CA),
  244. .CP0_Config2 = MIPS_CONFIG2,
  245. .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
  246. .CP0_LLAddr_rw_bitmask = 0,
  247. .CP0_LLAddr_shift = 4,
  248. .SYNCI_Step = 32,
  249. .CCRes = 2,
  250. /* No DSP implemented. */
  251. .CP0_Status_rw_bitmask = 0x3678FF1F,
  252. .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
  253. (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
  254. .SEGBITS = 32,
  255. .PABITS = 32,
  256. .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
  257. .mmu_type = MMU_TYPE_R4000,
  258. },
  259. {
  260. .name = "34Kf",
  261. .CP0_PRid = 0x00019500,
  262. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  263. (MMU_TYPE_R4000 << CP0C0_MT),
  264. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
  265. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  266. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  267. (1 << CP0C1_CA),
  268. .CP0_Config2 = MIPS_CONFIG2,
  269. .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT),
  270. .CP0_LLAddr_rw_bitmask = 0,
  271. .CP0_LLAddr_shift = 0,
  272. .SYNCI_Step = 32,
  273. .CCRes = 2,
  274. /* No DSP implemented. */
  275. .CP0_Status_rw_bitmask = 0x3678FF1F,
  276. /* No DSP implemented. */
  277. .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) |
  278. (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) |
  279. (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) |
  280. (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) |
  281. (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) |
  282. (0xff << CP0TCSt_TASID),
  283. .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
  284. (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
  285. .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS),
  286. .CP0_SRSConf0_rw_bitmask = 0x3fffffff,
  287. .CP0_SRSConf0 = (1 << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
  288. (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1),
  289. .CP0_SRSConf1_rw_bitmask = 0x3fffffff,
  290. .CP0_SRSConf1 = (1 << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) |
  291. (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4),
  292. .CP0_SRSConf2_rw_bitmask = 0x3fffffff,
  293. .CP0_SRSConf2 = (1 << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) |
  294. (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7),
  295. .CP0_SRSConf3_rw_bitmask = 0x3fffffff,
  296. .CP0_SRSConf3 = (1 << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) |
  297. (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10),
  298. .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
  299. .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
  300. (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
  301. .SEGBITS = 32,
  302. .PABITS = 32,
  303. .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT,
  304. .mmu_type = MMU_TYPE_R4000,
  305. },
  306. {
  307. .name = "74Kf",
  308. .CP0_PRid = 0x00019700,
  309. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
  310. (MMU_TYPE_R4000 << CP0C0_MT),
  311. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
  312. (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
  313. (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
  314. (1 << CP0C1_CA),
  315. .CP0_Config2 = MIPS_CONFIG2,
  316. .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_DSPP),
  317. .CP0_LLAddr_rw_bitmask = 0,
  318. .CP0_LLAddr_shift = 4,
  319. .SYNCI_Step = 32,
  320. .CCRes = 2,
  321. .CP0_Status_rw_bitmask = 0x3778FF1F,
  322. .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
  323. (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
  324. .SEGBITS = 32,
  325. .PABITS = 32,
  326. .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_DSPR2,
  327. .mmu_type = MMU_TYPE_R4000,
  328. },
  329. #if defined(TARGET_MIPS64)
  330. {
  331. .name = "R4000",
  332. .CP0_PRid = 0x00000400,
  333. /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
  334. .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
  335. /* Note: Config1 is only used internally, the R4000 has only Config0. */
  336. .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
  337. .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
  338. .CP0_LLAddr_shift = 4,
  339. .SYNCI_Step = 16,
  340. .CCRes = 2,
  341. .CP0_Status_rw_bitmask = 0x3678FFFF,
  342. /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */
  343. .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
  344. .SEGBITS = 40,
  345. .PABITS = 36,
  346. .insn_flags = CPU_MIPS3,
  347. .mmu_type = MMU_TYPE_R4000,
  348. },
  349. {
  350. .name = "VR5432",
  351. .CP0_PRid = 0x00005400,
  352. /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
  353. .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
  354. .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
  355. .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL,
  356. .CP0_LLAddr_shift = 4,
  357. .SYNCI_Step = 16,
  358. .CCRes = 2,
  359. .CP0_Status_rw_bitmask = 0x3678FFFF,
  360. /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */
  361. .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV),
  362. .SEGBITS = 40,
  363. .PABITS = 32,
  364. .insn_flags = CPU_VR54XX,
  365. .mmu_type = MMU_TYPE_R4000,
  366. },
  367. {
  368. .name = "5Kc",
  369. .CP0_PRid = 0x00018100,
  370. .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
  371. (MMU_TYPE_R4000 << CP0C0_MT),
  372. .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
  373. (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
  374. (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
  375. (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  376. .CP0_Config2 = MIPS_CONFIG2,
  377. .CP0_Config3 = MIPS_CONFIG3,
  378. .CP0_LLAddr_rw_bitmask = 0,
  379. .CP0_LLAddr_shift = 4,
  380. .SYNCI_Step = 32,
  381. .CCRes = 2,
  382. .CP0_Status_rw_bitmask = 0x32F8FFFF,
  383. .SEGBITS = 42,
  384. .PABITS = 36,
  385. .insn_flags = CPU_MIPS64,
  386. .mmu_type = MMU_TYPE_R4000,
  387. },
  388. {
  389. .name = "5Kf",
  390. .CP0_PRid = 0x00018100,
  391. .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
  392. (MMU_TYPE_R4000 << CP0C0_MT),
  393. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
  394. (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
  395. (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
  396. (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  397. .CP0_Config2 = MIPS_CONFIG2,
  398. .CP0_Config3 = MIPS_CONFIG3,
  399. .CP0_LLAddr_rw_bitmask = 0,
  400. .CP0_LLAddr_shift = 4,
  401. .SYNCI_Step = 32,
  402. .CCRes = 2,
  403. .CP0_Status_rw_bitmask = 0x36F8FFFF,
  404. /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
  405. .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
  406. (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
  407. .SEGBITS = 42,
  408. .PABITS = 36,
  409. .insn_flags = CPU_MIPS64,
  410. .mmu_type = MMU_TYPE_R4000,
  411. },
  412. {
  413. .name = "20Kc",
  414. /* We emulate a later version of the 20Kc, earlier ones had a broken
  415. WAIT instruction. */
  416. .CP0_PRid = 0x000182a0,
  417. .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
  418. (MMU_TYPE_R4000 << CP0C0_MT) | (1 << CP0C0_VI),
  419. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) |
  420. (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
  421. (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
  422. (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  423. .CP0_Config2 = MIPS_CONFIG2,
  424. .CP0_Config3 = MIPS_CONFIG3,
  425. .CP0_LLAddr_rw_bitmask = 0,
  426. .CP0_LLAddr_shift = 0,
  427. .SYNCI_Step = 32,
  428. .CCRes = 1,
  429. .CP0_Status_rw_bitmask = 0x36FBFFFF,
  430. /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
  431. .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
  432. (1 << FCR0_D) | (1 << FCR0_S) |
  433. (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
  434. .SEGBITS = 40,
  435. .PABITS = 36,
  436. .insn_flags = CPU_MIPS64 | ASE_MIPS3D,
  437. .mmu_type = MMU_TYPE_R4000,
  438. },
  439. {
  440. /* A generic CPU providing MIPS64 Release 2 features.
  441. FIXME: Eventually this should be replaced by a real CPU model. */
  442. .name = "MIPS64R2-generic",
  443. .CP0_PRid = 0x00010000,
  444. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
  445. (MMU_TYPE_R4000 << CP0C0_MT),
  446. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
  447. (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
  448. (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
  449. (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  450. .CP0_Config2 = MIPS_CONFIG2,
  451. .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
  452. .CP0_LLAddr_rw_bitmask = 0,
  453. .CP0_LLAddr_shift = 0,
  454. .SYNCI_Step = 32,
  455. .CCRes = 2,
  456. .CP0_Status_rw_bitmask = 0x36FBFFFF,
  457. .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
  458. (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
  459. (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
  460. .SEGBITS = 42,
  461. /* The architectural limit is 59, but we have hardcoded 36 bit
  462. in some places...
  463. .PABITS = 59, */ /* the architectural limit */
  464. .PABITS = 36,
  465. .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
  466. .mmu_type = MMU_TYPE_R4000,
  467. },
  468. {
  469. .name = "Loongson-2E",
  470. .CP0_PRid = 0x6302,
  471. /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
  472. .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
  473. (0x1<<4) | (0x1<<1),
  474. /* Note: Config1 is only used internally, Loongson-2E has only Config0. */
  475. .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
  476. .SYNCI_Step = 16,
  477. .CCRes = 2,
  478. .CP0_Status_rw_bitmask = 0x35D0FFFF,
  479. .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
  480. .SEGBITS = 40,
  481. .PABITS = 40,
  482. .insn_flags = CPU_LOONGSON2E,
  483. .mmu_type = MMU_TYPE_R4000,
  484. },
  485. {
  486. .name = "Loongson-2F",
  487. .CP0_PRid = 0x6303,
  488. /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/
  489. .CP0_Config0 = (0x1<<17) | (0x1<<16) | (0x1<<11) | (0x1<<8) | (0x1<<5) |
  490. (0x1<<4) | (0x1<<1),
  491. /* Note: Config1 is only used internally, Loongson-2F has only Config0. */
  492. .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
  493. .SYNCI_Step = 16,
  494. .CCRes = 2,
  495. .CP0_Status_rw_bitmask = 0xF5D0FF1F, /*bit5:7 not writable*/
  496. .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x1 << FCR0_REV),
  497. .SEGBITS = 40,
  498. .PABITS = 40,
  499. .insn_flags = CPU_LOONGSON2F,
  500. .mmu_type = MMU_TYPE_R4000,
  501. },
  502. {
  503. /* A generic CPU providing MIPS64 ASE DSP 2 features.
  504. FIXME: Eventually this should be replaced by a real CPU model. */
  505. .name = "mips64dspr2",
  506. .CP0_PRid = 0x00010000,
  507. .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
  508. (MMU_TYPE_R4000 << CP0C0_MT),
  509. .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
  510. (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
  511. (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
  512. (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  513. .CP0_Config2 = MIPS_CONFIG2,
  514. .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
  515. .CP0_LLAddr_rw_bitmask = 0,
  516. .CP0_LLAddr_shift = 0,
  517. .SYNCI_Step = 32,
  518. .CCRes = 2,
  519. .CP0_Status_rw_bitmask = 0x37FBFFFF,
  520. .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
  521. (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
  522. (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
  523. .SEGBITS = 42,
  524. /* The architectural limit is 59, but we have hardcoded 36 bit
  525. in some places...
  526. .PABITS = 59, */ /* the architectural limit */
  527. .PABITS = 36,
  528. .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSPR2,
  529. .mmu_type = MMU_TYPE_R4000,
  530. },
  531. #endif
  532. };
  533. static const mips_def_t *cpu_mips_find_by_name (const char *name)
  534. {
  535. int i;
  536. for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
  537. if (strcasecmp(name, mips_defs[i].name) == 0) {
  538. return &mips_defs[i];
  539. }
  540. }
  541. return NULL;
  542. }
  543. void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf)
  544. {
  545. int i;
  546. for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
  547. (*cpu_fprintf)(f, "MIPS '%s'\n",
  548. mips_defs[i].name);
  549. }
  550. }
  551. #ifndef CONFIG_USER_ONLY
  552. static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def)
  553. {
  554. env->tlb->nb_tlb = 1;
  555. env->tlb->map_address = &no_mmu_map_address;
  556. }
  557. static void fixed_mmu_init (CPUMIPSState *env, const mips_def_t *def)
  558. {
  559. env->tlb->nb_tlb = 1;
  560. env->tlb->map_address = &fixed_mmu_map_address;
  561. }
  562. static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def)
  563. {
  564. env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
  565. env->tlb->map_address = &r4k_map_address;
  566. env->tlb->helper_tlbwi = r4k_helper_tlbwi;
  567. env->tlb->helper_tlbwr = r4k_helper_tlbwr;
  568. env->tlb->helper_tlbp = r4k_helper_tlbp;
  569. env->tlb->helper_tlbr = r4k_helper_tlbr;
  570. }
  571. static void mmu_init (CPUMIPSState *env, const mips_def_t *def)
  572. {
  573. env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext));
  574. switch (def->mmu_type) {
  575. case MMU_TYPE_NONE:
  576. no_mmu_init(env, def);
  577. break;
  578. case MMU_TYPE_R4000:
  579. r4k_mmu_init(env, def);
  580. break;
  581. case MMU_TYPE_FMT:
  582. fixed_mmu_init(env, def);
  583. break;
  584. case MMU_TYPE_R3000:
  585. case MMU_TYPE_R6000:
  586. case MMU_TYPE_R8000:
  587. default:
  588. cpu_abort(env, "MMU type not supported\n");
  589. }
  590. }
  591. #endif /* CONFIG_USER_ONLY */
  592. static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
  593. {
  594. int i;
  595. for (i = 0; i < MIPS_FPU_MAX; i++)
  596. env->fpus[i].fcr0 = def->CP1_fcr0;
  597. memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
  598. }
  599. static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
  600. {
  601. env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext));
  602. /* MVPConf1 implemented, TLB sharable, no gating storage support,
  603. programmable cache partitioning implemented, number of allocatable
  604. and sharable TLB entries, MVP has allocatable TCs, 2 VPEs
  605. implemented, 5 TCs implemented. */
  606. env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) |
  607. (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) |
  608. // TODO: actually do 2 VPEs.
  609. // (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
  610. // (0x04 << CP0MVPC0_PTC);
  611. (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
  612. (0x00 << CP0MVPC0_PTC);
  613. #if !defined(CONFIG_USER_ONLY)
  614. /* Usermode has no TLB support */
  615. env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
  616. #endif
  617. /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
  618. no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
  619. env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) |
  620. (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
  621. (0x1 << CP0MVPC1_PCP1);
  622. }