helper.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421
  1. /*
  2. * sparc helpers
  3. *
  4. * Copyright (c) 2003-2005 Fabrice Bellard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
  19. */
  20. #include <stdarg.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <inttypes.h>
  25. #include <signal.h>
  26. #include <assert.h>
  27. #include "cpu.h"
  28. #include "exec-all.h"
  29. #include "qemu-common.h"
  30. //#define DEBUG_MMU
  31. //#define DEBUG_FEATURES
  32. static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
  33. /* Sparc MMU emulation */
  34. /* thread support */
  35. static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
  36. void cpu_lock(void)
  37. {
  38. spin_lock(&global_cpu_lock);
  39. }
  40. void cpu_unlock(void)
  41. {
  42. spin_unlock(&global_cpu_lock);
  43. }
  44. #if defined(CONFIG_USER_ONLY)
  45. int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
  46. int mmu_idx, int is_softmmu)
  47. {
  48. if (rw & 2)
  49. env1->exception_index = TT_TFAULT;
  50. else
  51. env1->exception_index = TT_DFAULT;
  52. return 1;
  53. }
  54. #else
  55. #ifndef TARGET_SPARC64
  56. /*
  57. * Sparc V8 Reference MMU (SRMMU)
  58. */
  59. static const int access_table[8][8] = {
  60. { 0, 0, 0, 0, 8, 0, 12, 12 },
  61. { 0, 0, 0, 0, 8, 0, 0, 0 },
  62. { 8, 8, 0, 0, 0, 8, 12, 12 },
  63. { 8, 8, 0, 0, 0, 8, 0, 0 },
  64. { 8, 0, 8, 0, 8, 8, 12, 12 },
  65. { 8, 0, 8, 0, 8, 0, 8, 0 },
  66. { 8, 8, 8, 0, 8, 8, 12, 12 },
  67. { 8, 8, 8, 0, 8, 8, 8, 0 }
  68. };
  69. static const int perm_table[2][8] = {
  70. {
  71. PAGE_READ,
  72. PAGE_READ | PAGE_WRITE,
  73. PAGE_READ | PAGE_EXEC,
  74. PAGE_READ | PAGE_WRITE | PAGE_EXEC,
  75. PAGE_EXEC,
  76. PAGE_READ | PAGE_WRITE,
  77. PAGE_READ | PAGE_EXEC,
  78. PAGE_READ | PAGE_WRITE | PAGE_EXEC
  79. },
  80. {
  81. PAGE_READ,
  82. PAGE_READ | PAGE_WRITE,
  83. PAGE_READ | PAGE_EXEC,
  84. PAGE_READ | PAGE_WRITE | PAGE_EXEC,
  85. PAGE_EXEC,
  86. PAGE_READ,
  87. 0,
  88. 0,
  89. }
  90. };
  91. static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
  92. int *prot, int *access_index,
  93. target_ulong address, int rw, int mmu_idx)
  94. {
  95. int access_perms = 0;
  96. target_phys_addr_t pde_ptr;
  97. uint32_t pde;
  98. target_ulong virt_addr;
  99. int error_code = 0, is_dirty, is_user;
  100. unsigned long page_offset;
  101. is_user = mmu_idx == MMU_USER_IDX;
  102. virt_addr = address & TARGET_PAGE_MASK;
  103. if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
  104. // Boot mode: instruction fetches are taken from PROM
  105. if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
  106. *physical = env->prom_addr | (address & 0x7ffffULL);
  107. *prot = PAGE_READ | PAGE_EXEC;
  108. return 0;
  109. }
  110. *physical = address;
  111. *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  112. return 0;
  113. }
  114. *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
  115. *physical = 0xffffffffffff0000ULL;
  116. /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
  117. /* Context base + context number */
  118. pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
  119. pde = ldl_phys(pde_ptr);
  120. /* Ctx pde */
  121. switch (pde & PTE_ENTRYTYPE_MASK) {
  122. default:
  123. case 0: /* Invalid */
  124. return 1 << 2;
  125. case 2: /* L0 PTE, maybe should not happen? */
  126. case 3: /* Reserved */
  127. return 4 << 2;
  128. case 1: /* L0 PDE */
  129. pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
  130. pde = ldl_phys(pde_ptr);
  131. switch (pde & PTE_ENTRYTYPE_MASK) {
  132. default:
  133. case 0: /* Invalid */
  134. return (1 << 8) | (1 << 2);
  135. case 3: /* Reserved */
  136. return (1 << 8) | (4 << 2);
  137. case 1: /* L1 PDE */
  138. pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
  139. pde = ldl_phys(pde_ptr);
  140. switch (pde & PTE_ENTRYTYPE_MASK) {
  141. default:
  142. case 0: /* Invalid */
  143. return (2 << 8) | (1 << 2);
  144. case 3: /* Reserved */
  145. return (2 << 8) | (4 << 2);
  146. case 1: /* L2 PDE */
  147. pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
  148. pde = ldl_phys(pde_ptr);
  149. switch (pde & PTE_ENTRYTYPE_MASK) {
  150. default:
  151. case 0: /* Invalid */
  152. return (3 << 8) | (1 << 2);
  153. case 1: /* PDE, should not happen */
  154. case 3: /* Reserved */
  155. return (3 << 8) | (4 << 2);
  156. case 2: /* L3 PTE */
  157. virt_addr = address & TARGET_PAGE_MASK;
  158. page_offset = (address & TARGET_PAGE_MASK) &
  159. (TARGET_PAGE_SIZE - 1);
  160. }
  161. break;
  162. case 2: /* L2 PTE */
  163. virt_addr = address & ~0x3ffff;
  164. page_offset = address & 0x3ffff;
  165. }
  166. break;
  167. case 2: /* L1 PTE */
  168. virt_addr = address & ~0xffffff;
  169. page_offset = address & 0xffffff;
  170. }
  171. }
  172. /* update page modified and dirty bits */
  173. is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
  174. if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
  175. pde |= PG_ACCESSED_MASK;
  176. if (is_dirty)
  177. pde |= PG_MODIFIED_MASK;
  178. stl_phys_notdirty(pde_ptr, pde);
  179. }
  180. /* check access */
  181. access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
  182. error_code = access_table[*access_index][access_perms];
  183. if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
  184. return error_code;
  185. /* the page can be put in the TLB */
  186. *prot = perm_table[is_user][access_perms];
  187. if (!(pde & PG_MODIFIED_MASK)) {
  188. /* only set write access if already dirty... otherwise wait
  189. for dirty access */
  190. *prot &= ~PAGE_WRITE;
  191. }
  192. /* Even if large ptes, we map only one 4KB page in the cache to
  193. avoid filling it too fast */
  194. *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
  195. return error_code;
  196. }
  197. /* Perform address translation */
  198. int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  199. int mmu_idx, int is_softmmu)
  200. {
  201. target_phys_addr_t paddr;
  202. target_ulong vaddr;
  203. int error_code = 0, prot, ret = 0, access_index;
  204. error_code = get_physical_address(env, &paddr, &prot, &access_index,
  205. address, rw, mmu_idx);
  206. if (error_code == 0) {
  207. vaddr = address & TARGET_PAGE_MASK;
  208. paddr &= TARGET_PAGE_MASK;
  209. #ifdef DEBUG_MMU
  210. printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
  211. TARGET_FMT_lx "\n", address, paddr, vaddr);
  212. #endif
  213. ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
  214. return ret;
  215. }
  216. if (env->mmuregs[3]) /* Fault status register */
  217. env->mmuregs[3] = 1; /* overflow (not read before another fault) */
  218. env->mmuregs[3] |= (access_index << 5) | error_code | 2;
  219. env->mmuregs[4] = address; /* Fault address register */
  220. if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) {
  221. // No fault mode: if a mapping is available, just override
  222. // permissions. If no mapping is available, redirect accesses to
  223. // neverland. Fake/overridden mappings will be flushed when
  224. // switching to normal mode.
  225. vaddr = address & TARGET_PAGE_MASK;
  226. prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  227. ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
  228. return ret;
  229. } else {
  230. if (rw & 2)
  231. env->exception_index = TT_TFAULT;
  232. else
  233. env->exception_index = TT_DFAULT;
  234. return 1;
  235. }
  236. }
  237. target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
  238. {
  239. target_phys_addr_t pde_ptr;
  240. uint32_t pde;
  241. /* Context base + context number */
  242. pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
  243. (env->mmuregs[2] << 2);
  244. pde = ldl_phys(pde_ptr);
  245. switch (pde & PTE_ENTRYTYPE_MASK) {
  246. default:
  247. case 0: /* Invalid */
  248. case 2: /* PTE, maybe should not happen? */
  249. case 3: /* Reserved */
  250. return 0;
  251. case 1: /* L1 PDE */
  252. if (mmulev == 3)
  253. return pde;
  254. pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
  255. pde = ldl_phys(pde_ptr);
  256. switch (pde & PTE_ENTRYTYPE_MASK) {
  257. default:
  258. case 0: /* Invalid */
  259. case 3: /* Reserved */
  260. return 0;
  261. case 2: /* L1 PTE */
  262. return pde;
  263. case 1: /* L2 PDE */
  264. if (mmulev == 2)
  265. return pde;
  266. pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
  267. pde = ldl_phys(pde_ptr);
  268. switch (pde & PTE_ENTRYTYPE_MASK) {
  269. default:
  270. case 0: /* Invalid */
  271. case 3: /* Reserved */
  272. return 0;
  273. case 2: /* L2 PTE */
  274. return pde;
  275. case 1: /* L3 PDE */
  276. if (mmulev == 1)
  277. return pde;
  278. pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
  279. pde = ldl_phys(pde_ptr);
  280. switch (pde & PTE_ENTRYTYPE_MASK) {
  281. default:
  282. case 0: /* Invalid */
  283. case 1: /* PDE, should not happen */
  284. case 3: /* Reserved */
  285. return 0;
  286. case 2: /* L3 PTE */
  287. return pde;
  288. }
  289. }
  290. }
  291. }
  292. return 0;
  293. }
  294. #ifdef DEBUG_MMU
  295. void dump_mmu(CPUState *env)
  296. {
  297. target_ulong va, va1, va2;
  298. unsigned int n, m, o;
  299. target_phys_addr_t pde_ptr, pa;
  300. uint32_t pde;
  301. printf("MMU dump:\n");
  302. pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
  303. pde = ldl_phys(pde_ptr);
  304. printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
  305. (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
  306. for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
  307. pde = mmu_probe(env, va, 2);
  308. if (pde) {
  309. pa = cpu_get_phys_page_debug(env, va);
  310. printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
  311. " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
  312. for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
  313. pde = mmu_probe(env, va1, 1);
  314. if (pde) {
  315. pa = cpu_get_phys_page_debug(env, va1);
  316. printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
  317. " PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
  318. for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
  319. pde = mmu_probe(env, va2, 0);
  320. if (pde) {
  321. pa = cpu_get_phys_page_debug(env, va2);
  322. printf(" VA: " TARGET_FMT_lx ", PA: "
  323. TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
  324. va2, pa, pde);
  325. }
  326. }
  327. }
  328. }
  329. }
  330. }
  331. printf("MMU dump ends\n");
  332. }
  333. #endif /* DEBUG_MMU */
  334. #else /* !TARGET_SPARC64 */
  335. /*
  336. * UltraSparc IIi I/DMMUs
  337. */
  338. static int get_physical_address_data(CPUState *env,
  339. target_phys_addr_t *physical, int *prot,
  340. target_ulong address, int rw, int is_user)
  341. {
  342. target_ulong mask;
  343. unsigned int i;
  344. if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
  345. *physical = address;
  346. *prot = PAGE_READ | PAGE_WRITE;
  347. return 0;
  348. }
  349. for (i = 0; i < 64; i++) {
  350. switch ((env->dtlb_tte[i] >> 61) & 3) {
  351. default:
  352. case 0x0: // 8k
  353. mask = 0xffffffffffffe000ULL;
  354. break;
  355. case 0x1: // 64k
  356. mask = 0xffffffffffff0000ULL;
  357. break;
  358. case 0x2: // 512k
  359. mask = 0xfffffffffff80000ULL;
  360. break;
  361. case 0x3: // 4M
  362. mask = 0xffffffffffc00000ULL;
  363. break;
  364. }
  365. // ctx match, vaddr match, valid?
  366. if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
  367. (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL) &&
  368. (env->dtlb_tte[i] & 0x8000000000000000ULL)) {
  369. // access ok?
  370. if (((env->dtlb_tte[i] & 0x4) && is_user) ||
  371. (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
  372. if (env->dmmuregs[3]) /* Fault status register */
  373. env->dmmuregs[3] = 2; /* overflow (not read before
  374. another fault) */
  375. env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
  376. env->dmmuregs[4] = address; /* Fault address register */
  377. env->exception_index = TT_DFAULT;
  378. #ifdef DEBUG_MMU
  379. printf("DFAULT at 0x%" PRIx64 "\n", address);
  380. #endif
  381. return 1;
  382. }
  383. *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
  384. (address & ~mask & 0x1fffffff000ULL);
  385. *prot = PAGE_READ;
  386. if (env->dtlb_tte[i] & 0x2)
  387. *prot |= PAGE_WRITE;
  388. return 0;
  389. }
  390. }
  391. #ifdef DEBUG_MMU
  392. printf("DMISS at 0x%" PRIx64 "\n", address);
  393. #endif
  394. env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
  395. env->exception_index = TT_DMISS;
  396. return 1;
  397. }
  398. static int get_physical_address_code(CPUState *env,
  399. target_phys_addr_t *physical, int *prot,
  400. target_ulong address, int is_user)
  401. {
  402. target_ulong mask;
  403. unsigned int i;
  404. if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
  405. *physical = address;
  406. *prot = PAGE_EXEC;
  407. return 0;
  408. }
  409. for (i = 0; i < 64; i++) {
  410. switch ((env->itlb_tte[i] >> 61) & 3) {
  411. default:
  412. case 0x0: // 8k
  413. mask = 0xffffffffffffe000ULL;
  414. break;
  415. case 0x1: // 64k
  416. mask = 0xffffffffffff0000ULL;
  417. break;
  418. case 0x2: // 512k
  419. mask = 0xfffffffffff80000ULL;
  420. break;
  421. case 0x3: // 4M
  422. mask = 0xffffffffffc00000ULL;
  423. break;
  424. }
  425. // ctx match, vaddr match, valid?
  426. if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
  427. (address & mask) == (env->itlb_tag[i] & ~0x1fffULL) &&
  428. (env->itlb_tte[i] & 0x8000000000000000ULL)) {
  429. // access ok?
  430. if ((env->itlb_tte[i] & 0x4) && is_user) {
  431. if (env->immuregs[3]) /* Fault status register */
  432. env->immuregs[3] = 2; /* overflow (not read before
  433. another fault) */
  434. env->immuregs[3] |= (is_user << 3) | 1;
  435. env->exception_index = TT_TFAULT;
  436. #ifdef DEBUG_MMU
  437. printf("TFAULT at 0x%" PRIx64 "\n", address);
  438. #endif
  439. return 1;
  440. }
  441. *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
  442. (address & ~mask & 0x1fffffff000ULL);
  443. *prot = PAGE_EXEC;
  444. return 0;
  445. }
  446. }
  447. #ifdef DEBUG_MMU
  448. printf("TMISS at 0x%" PRIx64 "\n", address);
  449. #endif
  450. env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
  451. env->exception_index = TT_TMISS;
  452. return 1;
  453. }
  454. static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
  455. int *prot, int *access_index,
  456. target_ulong address, int rw, int mmu_idx)
  457. {
  458. int is_user = mmu_idx == MMU_USER_IDX;
  459. if (rw == 2)
  460. return get_physical_address_code(env, physical, prot, address,
  461. is_user);
  462. else
  463. return get_physical_address_data(env, physical, prot, address, rw,
  464. is_user);
  465. }
  466. /* Perform address translation */
  467. int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  468. int mmu_idx, int is_softmmu)
  469. {
  470. target_ulong virt_addr, vaddr;
  471. target_phys_addr_t paddr;
  472. int error_code = 0, prot, ret = 0, access_index;
  473. error_code = get_physical_address(env, &paddr, &prot, &access_index,
  474. address, rw, mmu_idx);
  475. if (error_code == 0) {
  476. virt_addr = address & TARGET_PAGE_MASK;
  477. vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
  478. (TARGET_PAGE_SIZE - 1));
  479. #ifdef DEBUG_MMU
  480. printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
  481. "\n", address, paddr, vaddr);
  482. #endif
  483. ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
  484. return ret;
  485. }
  486. // XXX
  487. return 1;
  488. }
  489. #ifdef DEBUG_MMU
  490. void dump_mmu(CPUState *env)
  491. {
  492. unsigned int i;
  493. const char *mask;
  494. printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n",
  495. env->dmmuregs[1], env->dmmuregs[2]);
  496. if ((env->lsu & DMMU_E) == 0) {
  497. printf("DMMU disabled\n");
  498. } else {
  499. printf("DMMU dump:\n");
  500. for (i = 0; i < 64; i++) {
  501. switch ((env->dtlb_tte[i] >> 61) & 3) {
  502. default:
  503. case 0x0:
  504. mask = " 8k";
  505. break;
  506. case 0x1:
  507. mask = " 64k";
  508. break;
  509. case 0x2:
  510. mask = "512k";
  511. break;
  512. case 0x3:
  513. mask = " 4M";
  514. break;
  515. }
  516. if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
  517. printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
  518. ", %s, %s, %s, %s, ctx %" PRId64 "\n",
  519. env->dtlb_tag[i] & ~0x1fffULL,
  520. env->dtlb_tte[i] & 0x1ffffffe000ULL,
  521. mask,
  522. env->dtlb_tte[i] & 0x4? "priv": "user",
  523. env->dtlb_tte[i] & 0x2? "RW": "RO",
  524. env->dtlb_tte[i] & 0x40? "locked": "unlocked",
  525. env->dtlb_tag[i] & 0x1fffULL);
  526. }
  527. }
  528. }
  529. if ((env->lsu & IMMU_E) == 0) {
  530. printf("IMMU disabled\n");
  531. } else {
  532. printf("IMMU dump:\n");
  533. for (i = 0; i < 64; i++) {
  534. switch ((env->itlb_tte[i] >> 61) & 3) {
  535. default:
  536. case 0x0:
  537. mask = " 8k";
  538. break;
  539. case 0x1:
  540. mask = " 64k";
  541. break;
  542. case 0x2:
  543. mask = "512k";
  544. break;
  545. case 0x3:
  546. mask = " 4M";
  547. break;
  548. }
  549. if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
  550. printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
  551. ", %s, %s, %s, ctx %" PRId64 "\n",
  552. env->itlb_tag[i] & ~0x1fffULL,
  553. env->itlb_tte[i] & 0x1ffffffe000ULL,
  554. mask,
  555. env->itlb_tte[i] & 0x4? "priv": "user",
  556. env->itlb_tte[i] & 0x40? "locked": "unlocked",
  557. env->itlb_tag[i] & 0x1fffULL);
  558. }
  559. }
  560. }
  561. }
  562. #endif /* DEBUG_MMU */
  563. #endif /* TARGET_SPARC64 */
  564. #endif /* !CONFIG_USER_ONLY */
  565. #if defined(CONFIG_USER_ONLY)
  566. target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
  567. {
  568. return addr;
  569. }
  570. #else
  571. target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
  572. {
  573. target_phys_addr_t phys_addr;
  574. int prot, access_index;
  575. if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
  576. MMU_KERNEL_IDX) != 0)
  577. if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
  578. 0, MMU_KERNEL_IDX) != 0)
  579. return -1;
  580. if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
  581. return -1;
  582. return phys_addr;
  583. }
  584. #endif
  585. void cpu_reset(CPUSPARCState *env)
  586. {
  587. if (qemu_loglevel_mask(CPU_LOG_RESET)) {
  588. qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
  589. log_cpu_state(env, 0);
  590. }
  591. tlb_flush(env, 1);
  592. env->cwp = 0;
  593. env->wim = 1;
  594. env->regwptr = env->regbase + (env->cwp * 16);
  595. #if defined(CONFIG_USER_ONLY)
  596. #ifdef TARGET_SPARC64
  597. env->cleanwin = env->nwindows - 2;
  598. env->cansave = env->nwindows - 2;
  599. env->pstate = PS_RMO | PS_PEF | PS_IE;
  600. env->asi = 0x82; // Primary no-fault
  601. #endif
  602. #else
  603. env->psret = 0;
  604. env->psrs = 1;
  605. env->psrps = 1;
  606. #ifdef TARGET_SPARC64
  607. env->pstate = PS_PRIV;
  608. env->hpstate = HS_PRIV;
  609. env->tsptr = &env->ts[env->tl & MAXTL_MASK];
  610. env->lsu = 0;
  611. #else
  612. env->mmuregs[0] &= ~(MMU_E | MMU_NF);
  613. env->mmuregs[0] |= env->def->mmu_bm;
  614. #endif
  615. env->pc = 0;
  616. env->npc = env->pc + 4;
  617. #endif
  618. }
  619. static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
  620. {
  621. sparc_def_t def1, *def = &def1;
  622. if (cpu_sparc_find_by_name(def, cpu_model) < 0)
  623. return -1;
  624. env->def = qemu_mallocz(sizeof(*def));
  625. memcpy(env->def, def, sizeof(*def));
  626. #if defined(CONFIG_USER_ONLY)
  627. if ((env->def->features & CPU_FEATURE_FLOAT))
  628. env->def->features |= CPU_FEATURE_FLOAT128;
  629. #endif
  630. env->cpu_model_str = cpu_model;
  631. env->version = def->iu_version;
  632. env->fsr = def->fpu_version;
  633. env->nwindows = def->nwindows;
  634. #if !defined(TARGET_SPARC64)
  635. env->mmuregs[0] |= def->mmu_version;
  636. cpu_sparc_set_id(env, 0);
  637. env->mxccregs[7] |= def->mxcc_version;
  638. #else
  639. env->mmu_version = def->mmu_version;
  640. env->maxtl = def->maxtl;
  641. env->version |= def->maxtl << 8;
  642. env->version |= def->nwindows - 1;
  643. #endif
  644. return 0;
  645. }
  646. static void cpu_sparc_close(CPUSPARCState *env)
  647. {
  648. free(env->def);
  649. free(env);
  650. }
  651. CPUSPARCState *cpu_sparc_init(const char *cpu_model)
  652. {
  653. CPUSPARCState *env;
  654. env = qemu_mallocz(sizeof(CPUSPARCState));
  655. cpu_exec_init(env);
  656. gen_intermediate_code_init(env);
  657. if (cpu_sparc_register(env, cpu_model) < 0) {
  658. cpu_sparc_close(env);
  659. return NULL;
  660. }
  661. cpu_reset(env);
  662. return env;
  663. }
  664. void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
  665. {
  666. #if !defined(TARGET_SPARC64)
  667. env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
  668. #endif
  669. }
  670. static const sparc_def_t sparc_defs[] = {
  671. #ifdef TARGET_SPARC64
  672. {
  673. .name = "Fujitsu Sparc64",
  674. .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
  675. .fpu_version = 0x00000000,
  676. .mmu_version = mmu_us_12,
  677. .nwindows = 4,
  678. .maxtl = 4,
  679. .features = CPU_DEFAULT_FEATURES,
  680. },
  681. {
  682. .name = "Fujitsu Sparc64 III",
  683. .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
  684. .fpu_version = 0x00000000,
  685. .mmu_version = mmu_us_12,
  686. .nwindows = 5,
  687. .maxtl = 4,
  688. .features = CPU_DEFAULT_FEATURES,
  689. },
  690. {
  691. .name = "Fujitsu Sparc64 IV",
  692. .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
  693. .fpu_version = 0x00000000,
  694. .mmu_version = mmu_us_12,
  695. .nwindows = 8,
  696. .maxtl = 5,
  697. .features = CPU_DEFAULT_FEATURES,
  698. },
  699. {
  700. .name = "Fujitsu Sparc64 V",
  701. .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
  702. .fpu_version = 0x00000000,
  703. .mmu_version = mmu_us_12,
  704. .nwindows = 8,
  705. .maxtl = 5,
  706. .features = CPU_DEFAULT_FEATURES,
  707. },
  708. {
  709. .name = "TI UltraSparc I",
  710. .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
  711. .fpu_version = 0x00000000,
  712. .mmu_version = mmu_us_12,
  713. .nwindows = 8,
  714. .maxtl = 5,
  715. .features = CPU_DEFAULT_FEATURES,
  716. },
  717. {
  718. .name = "TI UltraSparc II",
  719. .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
  720. .fpu_version = 0x00000000,
  721. .mmu_version = mmu_us_12,
  722. .nwindows = 8,
  723. .maxtl = 5,
  724. .features = CPU_DEFAULT_FEATURES,
  725. },
  726. {
  727. .name = "TI UltraSparc IIi",
  728. .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
  729. .fpu_version = 0x00000000,
  730. .mmu_version = mmu_us_12,
  731. .nwindows = 8,
  732. .maxtl = 5,
  733. .features = CPU_DEFAULT_FEATURES,
  734. },
  735. {
  736. .name = "TI UltraSparc IIe",
  737. .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
  738. .fpu_version = 0x00000000,
  739. .mmu_version = mmu_us_12,
  740. .nwindows = 8,
  741. .maxtl = 5,
  742. .features = CPU_DEFAULT_FEATURES,
  743. },
  744. {
  745. .name = "Sun UltraSparc III",
  746. .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
  747. .fpu_version = 0x00000000,
  748. .mmu_version = mmu_us_12,
  749. .nwindows = 8,
  750. .maxtl = 5,
  751. .features = CPU_DEFAULT_FEATURES,
  752. },
  753. {
  754. .name = "Sun UltraSparc III Cu",
  755. .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
  756. .fpu_version = 0x00000000,
  757. .mmu_version = mmu_us_3,
  758. .nwindows = 8,
  759. .maxtl = 5,
  760. .features = CPU_DEFAULT_FEATURES,
  761. },
  762. {
  763. .name = "Sun UltraSparc IIIi",
  764. .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
  765. .fpu_version = 0x00000000,
  766. .mmu_version = mmu_us_12,
  767. .nwindows = 8,
  768. .maxtl = 5,
  769. .features = CPU_DEFAULT_FEATURES,
  770. },
  771. {
  772. .name = "Sun UltraSparc IV",
  773. .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
  774. .fpu_version = 0x00000000,
  775. .mmu_version = mmu_us_4,
  776. .nwindows = 8,
  777. .maxtl = 5,
  778. .features = CPU_DEFAULT_FEATURES,
  779. },
  780. {
  781. .name = "Sun UltraSparc IV+",
  782. .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
  783. .fpu_version = 0x00000000,
  784. .mmu_version = mmu_us_12,
  785. .nwindows = 8,
  786. .maxtl = 5,
  787. .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
  788. },
  789. {
  790. .name = "Sun UltraSparc IIIi+",
  791. .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
  792. .fpu_version = 0x00000000,
  793. .mmu_version = mmu_us_3,
  794. .nwindows = 8,
  795. .maxtl = 5,
  796. .features = CPU_DEFAULT_FEATURES,
  797. },
  798. {
  799. .name = "Sun UltraSparc T1",
  800. // defined in sparc_ifu_fdp.v and ctu.h
  801. .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
  802. .fpu_version = 0x00000000,
  803. .mmu_version = mmu_sun4v,
  804. .nwindows = 8,
  805. .maxtl = 6,
  806. .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
  807. | CPU_FEATURE_GL,
  808. },
  809. {
  810. .name = "Sun UltraSparc T2",
  811. // defined in tlu_asi_ctl.v and n2_revid_cust.v
  812. .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
  813. .fpu_version = 0x00000000,
  814. .mmu_version = mmu_sun4v,
  815. .nwindows = 8,
  816. .maxtl = 6,
  817. .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
  818. | CPU_FEATURE_GL,
  819. },
  820. {
  821. .name = "NEC UltraSparc I",
  822. .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
  823. .fpu_version = 0x00000000,
  824. .mmu_version = mmu_us_12,
  825. .nwindows = 8,
  826. .maxtl = 5,
  827. .features = CPU_DEFAULT_FEATURES,
  828. },
  829. #else
  830. {
  831. .name = "Fujitsu MB86900",
  832. .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
  833. .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
  834. .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
  835. .mmu_bm = 0x00004000,
  836. .mmu_ctpr_mask = 0x007ffff0,
  837. .mmu_cxr_mask = 0x0000003f,
  838. .mmu_sfsr_mask = 0xffffffff,
  839. .mmu_trcr_mask = 0xffffffff,
  840. .nwindows = 7,
  841. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
  842. },
  843. {
  844. .name = "Fujitsu MB86904",
  845. .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
  846. .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
  847. .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
  848. .mmu_bm = 0x00004000,
  849. .mmu_ctpr_mask = 0x00ffffc0,
  850. .mmu_cxr_mask = 0x000000ff,
  851. .mmu_sfsr_mask = 0x00016fff,
  852. .mmu_trcr_mask = 0x00ffffff,
  853. .nwindows = 8,
  854. .features = CPU_DEFAULT_FEATURES,
  855. },
  856. {
  857. .name = "Fujitsu MB86907",
  858. .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
  859. .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
  860. .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
  861. .mmu_bm = 0x00004000,
  862. .mmu_ctpr_mask = 0xffffffc0,
  863. .mmu_cxr_mask = 0x000000ff,
  864. .mmu_sfsr_mask = 0x00016fff,
  865. .mmu_trcr_mask = 0xffffffff,
  866. .nwindows = 8,
  867. .features = CPU_DEFAULT_FEATURES,
  868. },
  869. {
  870. .name = "LSI L64811",
  871. .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
  872. .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
  873. .mmu_version = 0x10 << 24,
  874. .mmu_bm = 0x00004000,
  875. .mmu_ctpr_mask = 0x007ffff0,
  876. .mmu_cxr_mask = 0x0000003f,
  877. .mmu_sfsr_mask = 0xffffffff,
  878. .mmu_trcr_mask = 0xffffffff,
  879. .nwindows = 8,
  880. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
  881. CPU_FEATURE_FSMULD,
  882. },
  883. {
  884. .name = "Cypress CY7C601",
  885. .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
  886. .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
  887. .mmu_version = 0x10 << 24,
  888. .mmu_bm = 0x00004000,
  889. .mmu_ctpr_mask = 0x007ffff0,
  890. .mmu_cxr_mask = 0x0000003f,
  891. .mmu_sfsr_mask = 0xffffffff,
  892. .mmu_trcr_mask = 0xffffffff,
  893. .nwindows = 8,
  894. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
  895. CPU_FEATURE_FSMULD,
  896. },
  897. {
  898. .name = "Cypress CY7C611",
  899. .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
  900. .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
  901. .mmu_version = 0x10 << 24,
  902. .mmu_bm = 0x00004000,
  903. .mmu_ctpr_mask = 0x007ffff0,
  904. .mmu_cxr_mask = 0x0000003f,
  905. .mmu_sfsr_mask = 0xffffffff,
  906. .mmu_trcr_mask = 0xffffffff,
  907. .nwindows = 8,
  908. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
  909. CPU_FEATURE_FSMULD,
  910. },
  911. {
  912. .name = "TI MicroSparc I",
  913. .iu_version = 0x41000000,
  914. .fpu_version = 4 << 17,
  915. .mmu_version = 0x41000000,
  916. .mmu_bm = 0x00004000,
  917. .mmu_ctpr_mask = 0x007ffff0,
  918. .mmu_cxr_mask = 0x0000003f,
  919. .mmu_sfsr_mask = 0x00016fff,
  920. .mmu_trcr_mask = 0x0000003f,
  921. .nwindows = 7,
  922. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
  923. CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
  924. CPU_FEATURE_FMUL,
  925. },
  926. {
  927. .name = "TI MicroSparc II",
  928. .iu_version = 0x42000000,
  929. .fpu_version = 4 << 17,
  930. .mmu_version = 0x02000000,
  931. .mmu_bm = 0x00004000,
  932. .mmu_ctpr_mask = 0x00ffffc0,
  933. .mmu_cxr_mask = 0x000000ff,
  934. .mmu_sfsr_mask = 0x00016fff,
  935. .mmu_trcr_mask = 0x00ffffff,
  936. .nwindows = 8,
  937. .features = CPU_DEFAULT_FEATURES,
  938. },
  939. {
  940. .name = "TI MicroSparc IIep",
  941. .iu_version = 0x42000000,
  942. .fpu_version = 4 << 17,
  943. .mmu_version = 0x04000000,
  944. .mmu_bm = 0x00004000,
  945. .mmu_ctpr_mask = 0x00ffffc0,
  946. .mmu_cxr_mask = 0x000000ff,
  947. .mmu_sfsr_mask = 0x00016bff,
  948. .mmu_trcr_mask = 0x00ffffff,
  949. .nwindows = 8,
  950. .features = CPU_DEFAULT_FEATURES,
  951. },
  952. {
  953. .name = "TI SuperSparc 40", // STP1020NPGA
  954. .iu_version = 0x41000000, // SuperSPARC 2.x
  955. .fpu_version = 0 << 17,
  956. .mmu_version = 0x00000800, // SuperSPARC 2.x, no MXCC
  957. .mmu_bm = 0x00002000,
  958. .mmu_ctpr_mask = 0xffffffc0,
  959. .mmu_cxr_mask = 0x0000ffff,
  960. .mmu_sfsr_mask = 0xffffffff,
  961. .mmu_trcr_mask = 0xffffffff,
  962. .nwindows = 8,
  963. .features = CPU_DEFAULT_FEATURES,
  964. },
  965. {
  966. .name = "TI SuperSparc 50", // STP1020PGA
  967. .iu_version = 0x40000000, // SuperSPARC 3.x
  968. .fpu_version = 0 << 17,
  969. .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
  970. .mmu_bm = 0x00002000,
  971. .mmu_ctpr_mask = 0xffffffc0,
  972. .mmu_cxr_mask = 0x0000ffff,
  973. .mmu_sfsr_mask = 0xffffffff,
  974. .mmu_trcr_mask = 0xffffffff,
  975. .nwindows = 8,
  976. .features = CPU_DEFAULT_FEATURES,
  977. },
  978. {
  979. .name = "TI SuperSparc 51",
  980. .iu_version = 0x40000000, // SuperSPARC 3.x
  981. .fpu_version = 0 << 17,
  982. .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
  983. .mmu_bm = 0x00002000,
  984. .mmu_ctpr_mask = 0xffffffc0,
  985. .mmu_cxr_mask = 0x0000ffff,
  986. .mmu_sfsr_mask = 0xffffffff,
  987. .mmu_trcr_mask = 0xffffffff,
  988. .mxcc_version = 0x00000104,
  989. .nwindows = 8,
  990. .features = CPU_DEFAULT_FEATURES,
  991. },
  992. {
  993. .name = "TI SuperSparc 60", // STP1020APGA
  994. .iu_version = 0x40000000, // SuperSPARC 3.x
  995. .fpu_version = 0 << 17,
  996. .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
  997. .mmu_bm = 0x00002000,
  998. .mmu_ctpr_mask = 0xffffffc0,
  999. .mmu_cxr_mask = 0x0000ffff,
  1000. .mmu_sfsr_mask = 0xffffffff,
  1001. .mmu_trcr_mask = 0xffffffff,
  1002. .nwindows = 8,
  1003. .features = CPU_DEFAULT_FEATURES,
  1004. },
  1005. {
  1006. .name = "TI SuperSparc 61",
  1007. .iu_version = 0x44000000, // SuperSPARC 3.x
  1008. .fpu_version = 0 << 17,
  1009. .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
  1010. .mmu_bm = 0x00002000,
  1011. .mmu_ctpr_mask = 0xffffffc0,
  1012. .mmu_cxr_mask = 0x0000ffff,
  1013. .mmu_sfsr_mask = 0xffffffff,
  1014. .mmu_trcr_mask = 0xffffffff,
  1015. .mxcc_version = 0x00000104,
  1016. .nwindows = 8,
  1017. .features = CPU_DEFAULT_FEATURES,
  1018. },
  1019. {
  1020. .name = "TI SuperSparc II",
  1021. .iu_version = 0x40000000, // SuperSPARC II 1.x
  1022. .fpu_version = 0 << 17,
  1023. .mmu_version = 0x08000000, // SuperSPARC II 1.x, MXCC
  1024. .mmu_bm = 0x00002000,
  1025. .mmu_ctpr_mask = 0xffffffc0,
  1026. .mmu_cxr_mask = 0x0000ffff,
  1027. .mmu_sfsr_mask = 0xffffffff,
  1028. .mmu_trcr_mask = 0xffffffff,
  1029. .mxcc_version = 0x00000104,
  1030. .nwindows = 8,
  1031. .features = CPU_DEFAULT_FEATURES,
  1032. },
  1033. {
  1034. .name = "Ross RT625",
  1035. .iu_version = 0x1e000000,
  1036. .fpu_version = 1 << 17,
  1037. .mmu_version = 0x1e000000,
  1038. .mmu_bm = 0x00004000,
  1039. .mmu_ctpr_mask = 0x007ffff0,
  1040. .mmu_cxr_mask = 0x0000003f,
  1041. .mmu_sfsr_mask = 0xffffffff,
  1042. .mmu_trcr_mask = 0xffffffff,
  1043. .nwindows = 8,
  1044. .features = CPU_DEFAULT_FEATURES,
  1045. },
  1046. {
  1047. .name = "Ross RT620",
  1048. .iu_version = 0x1f000000,
  1049. .fpu_version = 1 << 17,
  1050. .mmu_version = 0x1f000000,
  1051. .mmu_bm = 0x00004000,
  1052. .mmu_ctpr_mask = 0x007ffff0,
  1053. .mmu_cxr_mask = 0x0000003f,
  1054. .mmu_sfsr_mask = 0xffffffff,
  1055. .mmu_trcr_mask = 0xffffffff,
  1056. .nwindows = 8,
  1057. .features = CPU_DEFAULT_FEATURES,
  1058. },
  1059. {
  1060. .name = "BIT B5010",
  1061. .iu_version = 0x20000000,
  1062. .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
  1063. .mmu_version = 0x20000000,
  1064. .mmu_bm = 0x00004000,
  1065. .mmu_ctpr_mask = 0x007ffff0,
  1066. .mmu_cxr_mask = 0x0000003f,
  1067. .mmu_sfsr_mask = 0xffffffff,
  1068. .mmu_trcr_mask = 0xffffffff,
  1069. .nwindows = 8,
  1070. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
  1071. CPU_FEATURE_FSMULD,
  1072. },
  1073. {
  1074. .name = "Matsushita MN10501",
  1075. .iu_version = 0x50000000,
  1076. .fpu_version = 0 << 17,
  1077. .mmu_version = 0x50000000,
  1078. .mmu_bm = 0x00004000,
  1079. .mmu_ctpr_mask = 0x007ffff0,
  1080. .mmu_cxr_mask = 0x0000003f,
  1081. .mmu_sfsr_mask = 0xffffffff,
  1082. .mmu_trcr_mask = 0xffffffff,
  1083. .nwindows = 8,
  1084. .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
  1085. CPU_FEATURE_FSMULD,
  1086. },
  1087. {
  1088. .name = "Weitek W8601",
  1089. .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
  1090. .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
  1091. .mmu_version = 0x10 << 24,
  1092. .mmu_bm = 0x00004000,
  1093. .mmu_ctpr_mask = 0x007ffff0,
  1094. .mmu_cxr_mask = 0x0000003f,
  1095. .mmu_sfsr_mask = 0xffffffff,
  1096. .mmu_trcr_mask = 0xffffffff,
  1097. .nwindows = 8,
  1098. .features = CPU_DEFAULT_FEATURES,
  1099. },
  1100. {
  1101. .name = "LEON2",
  1102. .iu_version = 0xf2000000,
  1103. .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
  1104. .mmu_version = 0xf2000000,
  1105. .mmu_bm = 0x00004000,
  1106. .mmu_ctpr_mask = 0x007ffff0,
  1107. .mmu_cxr_mask = 0x0000003f,
  1108. .mmu_sfsr_mask = 0xffffffff,
  1109. .mmu_trcr_mask = 0xffffffff,
  1110. .nwindows = 8,
  1111. .features = CPU_DEFAULT_FEATURES,
  1112. },
  1113. {
  1114. .name = "LEON3",
  1115. .iu_version = 0xf3000000,
  1116. .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
  1117. .mmu_version = 0xf3000000,
  1118. .mmu_bm = 0x00004000,
  1119. .mmu_ctpr_mask = 0x007ffff0,
  1120. .mmu_cxr_mask = 0x0000003f,
  1121. .mmu_sfsr_mask = 0xffffffff,
  1122. .mmu_trcr_mask = 0xffffffff,
  1123. .nwindows = 8,
  1124. .features = CPU_DEFAULT_FEATURES,
  1125. },
  1126. #endif
  1127. };
  1128. static const char * const feature_name[] = {
  1129. "float",
  1130. "float128",
  1131. "swap",
  1132. "mul",
  1133. "div",
  1134. "flush",
  1135. "fsqrt",
  1136. "fmul",
  1137. "vis1",
  1138. "vis2",
  1139. "fsmuld",
  1140. "hypv",
  1141. "cmt",
  1142. "gl",
  1143. };
  1144. static void print_features(FILE *f,
  1145. int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  1146. uint32_t features, const char *prefix)
  1147. {
  1148. unsigned int i;
  1149. for (i = 0; i < ARRAY_SIZE(feature_name); i++)
  1150. if (feature_name[i] && (features & (1 << i))) {
  1151. if (prefix)
  1152. (*cpu_fprintf)(f, "%s", prefix);
  1153. (*cpu_fprintf)(f, "%s ", feature_name[i]);
  1154. }
  1155. }
  1156. static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
  1157. {
  1158. unsigned int i;
  1159. for (i = 0; i < ARRAY_SIZE(feature_name); i++)
  1160. if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
  1161. *features |= 1 << i;
  1162. return;
  1163. }
  1164. fprintf(stderr, "CPU feature %s not found\n", flagname);
  1165. }
  1166. static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
  1167. {
  1168. unsigned int i;
  1169. const sparc_def_t *def = NULL;
  1170. char *s = strdup(cpu_model);
  1171. char *featurestr, *name = strtok(s, ",");
  1172. uint32_t plus_features = 0;
  1173. uint32_t minus_features = 0;
  1174. long long iu_version;
  1175. uint32_t fpu_version, mmu_version, nwindows;
  1176. for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
  1177. if (strcasecmp(name, sparc_defs[i].name) == 0) {
  1178. def = &sparc_defs[i];
  1179. }
  1180. }
  1181. if (!def)
  1182. goto error;
  1183. memcpy(cpu_def, def, sizeof(*def));
  1184. featurestr = strtok(NULL, ",");
  1185. while (featurestr) {
  1186. char *val;
  1187. if (featurestr[0] == '+') {
  1188. add_flagname_to_bitmaps(featurestr + 1, &plus_features);
  1189. } else if (featurestr[0] == '-') {
  1190. add_flagname_to_bitmaps(featurestr + 1, &minus_features);
  1191. } else if ((val = strchr(featurestr, '='))) {
  1192. *val = 0; val++;
  1193. if (!strcmp(featurestr, "iu_version")) {
  1194. char *err;
  1195. iu_version = strtoll(val, &err, 0);
  1196. if (!*val || *err) {
  1197. fprintf(stderr, "bad numerical value %s\n", val);
  1198. goto error;
  1199. }
  1200. cpu_def->iu_version = iu_version;
  1201. #ifdef DEBUG_FEATURES
  1202. fprintf(stderr, "iu_version %llx\n", iu_version);
  1203. #endif
  1204. } else if (!strcmp(featurestr, "fpu_version")) {
  1205. char *err;
  1206. fpu_version = strtol(val, &err, 0);
  1207. if (!*val || *err) {
  1208. fprintf(stderr, "bad numerical value %s\n", val);
  1209. goto error;
  1210. }
  1211. cpu_def->fpu_version = fpu_version;
  1212. #ifdef DEBUG_FEATURES
  1213. fprintf(stderr, "fpu_version %llx\n", fpu_version);
  1214. #endif
  1215. } else if (!strcmp(featurestr, "mmu_version")) {
  1216. char *err;
  1217. mmu_version = strtol(val, &err, 0);
  1218. if (!*val || *err) {
  1219. fprintf(stderr, "bad numerical value %s\n", val);
  1220. goto error;
  1221. }
  1222. cpu_def->mmu_version = mmu_version;
  1223. #ifdef DEBUG_FEATURES
  1224. fprintf(stderr, "mmu_version %llx\n", mmu_version);
  1225. #endif
  1226. } else if (!strcmp(featurestr, "nwindows")) {
  1227. char *err;
  1228. nwindows = strtol(val, &err, 0);
  1229. if (!*val || *err || nwindows > MAX_NWINDOWS ||
  1230. nwindows < MIN_NWINDOWS) {
  1231. fprintf(stderr, "bad numerical value %s\n", val);
  1232. goto error;
  1233. }
  1234. cpu_def->nwindows = nwindows;
  1235. #ifdef DEBUG_FEATURES
  1236. fprintf(stderr, "nwindows %d\n", nwindows);
  1237. #endif
  1238. } else {
  1239. fprintf(stderr, "unrecognized feature %s\n", featurestr);
  1240. goto error;
  1241. }
  1242. } else {
  1243. fprintf(stderr, "feature string `%s' not in format "
  1244. "(+feature|-feature|feature=xyz)\n", featurestr);
  1245. goto error;
  1246. }
  1247. featurestr = strtok(NULL, ",");
  1248. }
  1249. cpu_def->features |= plus_features;
  1250. cpu_def->features &= ~minus_features;
  1251. #ifdef DEBUG_FEATURES
  1252. print_features(stderr, fprintf, cpu_def->features, NULL);
  1253. #endif
  1254. free(s);
  1255. return 0;
  1256. error:
  1257. free(s);
  1258. return -1;
  1259. }
  1260. void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
  1261. {
  1262. unsigned int i;
  1263. for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
  1264. (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
  1265. sparc_defs[i].name,
  1266. sparc_defs[i].iu_version,
  1267. sparc_defs[i].fpu_version,
  1268. sparc_defs[i].mmu_version,
  1269. sparc_defs[i].nwindows);
  1270. print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
  1271. ~sparc_defs[i].features, "-");
  1272. print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
  1273. sparc_defs[i].features, "+");
  1274. (*cpu_fprintf)(f, "\n");
  1275. }
  1276. (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
  1277. print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
  1278. (*cpu_fprintf)(f, "\n");
  1279. (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
  1280. print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
  1281. (*cpu_fprintf)(f, "\n");
  1282. (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
  1283. "fpu_version mmu_version nwindows\n");
  1284. }
  1285. #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
  1286. void cpu_dump_state(CPUState *env, FILE *f,
  1287. int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  1288. int flags)
  1289. {
  1290. int i, x;
  1291. cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
  1292. env->npc);
  1293. cpu_fprintf(f, "General Registers:\n");
  1294. for (i = 0; i < 4; i++)
  1295. cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
  1296. cpu_fprintf(f, "\n");
  1297. for (; i < 8; i++)
  1298. cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
  1299. cpu_fprintf(f, "\nCurrent Register Window:\n");
  1300. for (x = 0; x < 3; x++) {
  1301. for (i = 0; i < 4; i++)
  1302. cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
  1303. (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
  1304. env->regwptr[i + x * 8]);
  1305. cpu_fprintf(f, "\n");
  1306. for (; i < 8; i++)
  1307. cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
  1308. (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
  1309. env->regwptr[i + x * 8]);
  1310. cpu_fprintf(f, "\n");
  1311. }
  1312. cpu_fprintf(f, "\nFloating Point Registers:\n");
  1313. for (i = 0; i < 32; i++) {
  1314. if ((i & 3) == 0)
  1315. cpu_fprintf(f, "%%f%02d:", i);
  1316. cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
  1317. if ((i & 3) == 3)
  1318. cpu_fprintf(f, "\n");
  1319. }
  1320. #ifdef TARGET_SPARC64
  1321. cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
  1322. env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
  1323. cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
  1324. "cleanwin %d cwp %d\n",
  1325. env->cansave, env->canrestore, env->otherwin, env->wstate,
  1326. env->cleanwin, env->nwindows - 1 - env->cwp);
  1327. #else
  1328. cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
  1329. GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
  1330. GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
  1331. env->psrs?'S':'-', env->psrps?'P':'-',
  1332. env->psret?'E':'-', env->wim);
  1333. #endif
  1334. cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr);
  1335. }