alpha_palcode.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. /*
  2. * Alpha emulation - PALcode emulation for qemu.
  3. *
  4. * Copyright (c) 2007 Jocelyn Mayer
  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 <stdint.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include "qemu.h"
  24. #include "cpu.h"
  25. #include "exec-all.h"
  26. #if !defined (CONFIG_USER_ONLY)
  27. /* Shared handlers */
  28. static void pal_reset (CPUState *env);
  29. /* Console handlers */
  30. static void pal_console_call (CPUState *env, uint32_t palcode);
  31. /* OpenVMS handlers */
  32. static void pal_openvms_call (CPUState *env, uint32_t palcode);
  33. /* UNIX / Linux handlers */
  34. static void pal_unix_call (CPUState *env, uint32_t palcode);
  35. pal_handler_t pal_handlers[] = {
  36. /* Console handler */
  37. {
  38. .reset = &pal_reset,
  39. .call_pal = &pal_console_call,
  40. },
  41. /* OpenVMS handler */
  42. {
  43. .reset = &pal_reset,
  44. .call_pal = &pal_openvms_call,
  45. },
  46. /* UNIX / Linux handler */
  47. {
  48. .reset = &pal_reset,
  49. .call_pal = &pal_unix_call,
  50. },
  51. };
  52. #if 0
  53. /* One must explicitly check that the TB is valid and the FOE bit is reset */
  54. static void update_itb (void)
  55. {
  56. /* This writes into a temp register, not the actual one */
  57. mtpr(TB_TAG);
  58. mtpr(TB_CTL);
  59. /* This commits the TB update */
  60. mtpr(ITB_PTE);
  61. }
  62. static void update_dtb (void);
  63. {
  64. mtpr(TB_CTL);
  65. /* This write into a temp register, not the actual one */
  66. mtpr(TB_TAG);
  67. /* This commits the TB update */
  68. mtpr(DTB_PTE);
  69. }
  70. #endif
  71. static void pal_reset (CPUState *env)
  72. {
  73. }
  74. static void do_swappal (CPUState *env, uint64_t palid)
  75. {
  76. pal_handler_t *pal_handler;
  77. int status;
  78. status = 0;
  79. switch (palid) {
  80. case 0 ... 2:
  81. pal_handler = &pal_handlers[palid];
  82. env->pal_handler = pal_handler;
  83. env->ipr[IPR_PAL_BASE] = -1ULL;
  84. (*pal_handler->reset)(env);
  85. break;
  86. case 3 ... 255:
  87. /* Unknown identifier */
  88. env->ir[0] = 1;
  89. return;
  90. default:
  91. /* We were given the entry point address */
  92. env->pal_handler = NULL;
  93. env->ipr[IPR_PAL_BASE] = palid;
  94. env->pc = env->ipr[IPR_PAL_BASE];
  95. cpu_loop_exit();
  96. }
  97. }
  98. static void pal_console_call (CPUState *env, uint32_t palcode)
  99. {
  100. uint64_t palid;
  101. if (palcode < 0x00000080) {
  102. /* Privileged palcodes */
  103. if (!(env->ps >> 3)) {
  104. /* TODO: generate privilege exception */
  105. }
  106. }
  107. switch (palcode) {
  108. case 0x00000000:
  109. /* HALT */
  110. /* REQUIRED */
  111. break;
  112. case 0x00000001:
  113. /* CFLUSH */
  114. break;
  115. case 0x00000002:
  116. /* DRAINA */
  117. /* REQUIRED */
  118. /* Implemented as no-op */
  119. break;
  120. case 0x00000009:
  121. /* CSERVE */
  122. /* REQUIRED */
  123. break;
  124. case 0x0000000A:
  125. /* SWPPAL */
  126. /* REQUIRED */
  127. palid = env->ir[16];
  128. do_swappal(env, palid);
  129. break;
  130. case 0x00000080:
  131. /* BPT */
  132. /* REQUIRED */
  133. break;
  134. case 0x00000081:
  135. /* BUGCHK */
  136. /* REQUIRED */
  137. break;
  138. case 0x00000086:
  139. /* IMB */
  140. /* REQUIRED */
  141. /* Implemented as no-op */
  142. break;
  143. case 0x0000009E:
  144. /* RDUNIQUE */
  145. /* REQUIRED */
  146. break;
  147. case 0x0000009F:
  148. /* WRUNIQUE */
  149. /* REQUIRED */
  150. break;
  151. case 0x000000AA:
  152. /* GENTRAP */
  153. /* REQUIRED */
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. static void pal_openvms_call (CPUState *env, uint32_t palcode)
  160. {
  161. uint64_t palid, val, oldval;
  162. if (palcode < 0x00000080) {
  163. /* Privileged palcodes */
  164. if (!(env->ps >> 3)) {
  165. /* TODO: generate privilege exception */
  166. }
  167. }
  168. switch (palcode) {
  169. case 0x00000000:
  170. /* HALT */
  171. /* REQUIRED */
  172. break;
  173. case 0x00000001:
  174. /* CFLUSH */
  175. break;
  176. case 0x00000002:
  177. /* DRAINA */
  178. /* REQUIRED */
  179. /* Implemented as no-op */
  180. break;
  181. case 0x00000003:
  182. /* LDQP */
  183. break;
  184. case 0x00000004:
  185. /* STQP */
  186. break;
  187. case 0x00000005:
  188. /* SWPCTX */
  189. break;
  190. case 0x00000006:
  191. /* MFPR_ASN */
  192. if (cpu_alpha_mfpr(env, IPR_ASN, &val) == 0)
  193. env->ir[0] = val;
  194. break;
  195. case 0x00000007:
  196. /* MTPR_ASTEN */
  197. val = env->ir[16];
  198. if (cpu_alpha_mtpr(env, IPR_ASTEN, val, &oldval) == 1)
  199. env->ir[0] = val;
  200. break;
  201. case 0x00000008:
  202. /* MTPR_ASTSR */
  203. val = env->ir[16];
  204. if (cpu_alpha_mtpr(env, IPR_ASTSR, val, &oldval) == 1)
  205. env->ir[0] = val;
  206. break;
  207. case 0x00000009:
  208. /* CSERVE */
  209. /* REQUIRED */
  210. break;
  211. case 0x0000000A:
  212. /* SWPPAL */
  213. /* REQUIRED */
  214. palid = env->ir[16];
  215. do_swappal(env, palid);
  216. break;
  217. case 0x0000000B:
  218. /* MFPR_FEN */
  219. if (cpu_alpha_mfpr(env, IPR_FEN, &val) == 0)
  220. env->ir[0] = val;
  221. break;
  222. case 0x0000000C:
  223. /* MTPR_FEN */
  224. val = env->ir[16];
  225. if (cpu_alpha_mtpr(env, IPR_FEN, val, &oldval) == 1)
  226. env->ir[0] = val;
  227. break;
  228. case 0x0000000D:
  229. /* MTPR_IPIR */
  230. val = env->ir[16];
  231. if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
  232. env->ir[0] = val;
  233. break;
  234. case 0x0000000E:
  235. /* MFPR_IPL */
  236. if (cpu_alpha_mfpr(env, IPR_IPL, &val) == 0)
  237. env->ir[0] = val;
  238. break;
  239. case 0x0000000F:
  240. /* MTPR_IPL */
  241. val = env->ir[16];
  242. if (cpu_alpha_mtpr(env, IPR_IPL, val, &oldval) == 1)
  243. env->ir[0] = val;
  244. break;
  245. case 0x00000010:
  246. /* MFPR_MCES */
  247. if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
  248. env->ir[0] = val;
  249. break;
  250. case 0x00000011:
  251. /* MTPR_MCES */
  252. val = env->ir[16];
  253. if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
  254. env->ir[0] = val;
  255. break;
  256. case 0x00000012:
  257. /* MFPR_PCBB */
  258. if (cpu_alpha_mfpr(env, IPR_PCBB, &val) == 0)
  259. env->ir[0] = val;
  260. break;
  261. case 0x00000013:
  262. /* MFPR_PRBR */
  263. if (cpu_alpha_mfpr(env, IPR_PRBR, &val) == 0)
  264. env->ir[0] = val;
  265. break;
  266. case 0x00000014:
  267. /* MTPR_PRBR */
  268. val = env->ir[16];
  269. if (cpu_alpha_mtpr(env, IPR_PRBR, val, &oldval) == 1)
  270. env->ir[0] = val;
  271. break;
  272. case 0x00000015:
  273. /* MFPR_PTBR */
  274. if (cpu_alpha_mfpr(env, IPR_PTBR, &val) == 0)
  275. env->ir[0] = val;
  276. break;
  277. case 0x00000016:
  278. /* MFPR_SCBB */
  279. if (cpu_alpha_mfpr(env, IPR_SCBB, &val) == 0)
  280. env->ir[0] = val;
  281. break;
  282. case 0x00000017:
  283. /* MTPR_SCBB */
  284. val = env->ir[16];
  285. if (cpu_alpha_mtpr(env, IPR_SCBB, val, &oldval) == 1)
  286. env->ir[0] = val;
  287. break;
  288. case 0x00000018:
  289. /* MTPR_SIRR */
  290. val = env->ir[16];
  291. if (cpu_alpha_mtpr(env, IPR_SIRR, val, &oldval) == 1)
  292. env->ir[0] = val;
  293. break;
  294. case 0x00000019:
  295. /* MFPR_SISR */
  296. if (cpu_alpha_mfpr(env, IPR_SISR, &val) == 0)
  297. env->ir[0] = val;
  298. break;
  299. case 0x0000001A:
  300. /* MFPR_TBCHK */
  301. if (cpu_alpha_mfpr(env, IPR_TBCHK, &val) == 0)
  302. env->ir[0] = val;
  303. break;
  304. case 0x0000001B:
  305. /* MTPR_TBIA */
  306. val = env->ir[16];
  307. if (cpu_alpha_mtpr(env, IPR_TBIA, val, &oldval) == 1)
  308. env->ir[0] = val;
  309. break;
  310. case 0x0000001C:
  311. /* MTPR_TBIAP */
  312. val = env->ir[16];
  313. if (cpu_alpha_mtpr(env, IPR_TBIAP, val, &oldval) == 1)
  314. env->ir[0] = val;
  315. break;
  316. case 0x0000001D:
  317. /* MTPR_TBIS */
  318. val = env->ir[16];
  319. if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
  320. env->ir[0] = val;
  321. break;
  322. case 0x0000001E:
  323. /* MFPR_ESP */
  324. if (cpu_alpha_mfpr(env, IPR_ESP, &val) == 0)
  325. env->ir[0] = val;
  326. break;
  327. case 0x0000001F:
  328. /* MTPR_ESP */
  329. val = env->ir[16];
  330. if (cpu_alpha_mtpr(env, IPR_ESP, val, &oldval) == 1)
  331. env->ir[0] = val;
  332. break;
  333. case 0x00000020:
  334. /* MFPR_SSP */
  335. if (cpu_alpha_mfpr(env, IPR_SSP, &val) == 0)
  336. env->ir[0] = val;
  337. break;
  338. case 0x00000021:
  339. /* MTPR_SSP */
  340. val = env->ir[16];
  341. if (cpu_alpha_mtpr(env, IPR_SSP, val, &oldval) == 1)
  342. env->ir[0] = val;
  343. break;
  344. case 0x00000022:
  345. /* MFPR_USP */
  346. if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
  347. env->ir[0] = val;
  348. break;
  349. case 0x00000023:
  350. /* MTPR_USP */
  351. val = env->ir[16];
  352. if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
  353. env->ir[0] = val;
  354. break;
  355. case 0x00000024:
  356. /* MTPR_TBISD */
  357. val = env->ir[16];
  358. if (cpu_alpha_mtpr(env, IPR_TBISD, val, &oldval) == 1)
  359. env->ir[0] = val;
  360. break;
  361. case 0x00000025:
  362. /* MTPR_TBISI */
  363. val = env->ir[16];
  364. if (cpu_alpha_mtpr(env, IPR_TBISI, val, &oldval) == 1)
  365. env->ir[0] = val;
  366. break;
  367. case 0x00000026:
  368. /* MFPR_ASTEN */
  369. if (cpu_alpha_mfpr(env, IPR_ASTEN, &val) == 0)
  370. env->ir[0] = val;
  371. break;
  372. case 0x00000027:
  373. /* MFPR_ASTSR */
  374. if (cpu_alpha_mfpr(env, IPR_ASTSR, &val) == 0)
  375. env->ir[0] = val;
  376. break;
  377. case 0x00000029:
  378. /* MFPR_VPTB */
  379. if (cpu_alpha_mfpr(env, IPR_VPTB, &val) == 0)
  380. env->ir[0] = val;
  381. break;
  382. case 0x0000002A:
  383. /* MTPR_VPTB */
  384. val = env->ir[16];
  385. if (cpu_alpha_mtpr(env, IPR_VPTB, val, &oldval) == 1)
  386. env->ir[0] = val;
  387. break;
  388. case 0x0000002B:
  389. /* MTPR_PERFMON */
  390. val = env->ir[16];
  391. if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
  392. env->ir[0] = val;
  393. break;
  394. case 0x0000002E:
  395. /* MTPR_DATFX */
  396. val = env->ir[16];
  397. if (cpu_alpha_mtpr(env, IPR_DATFX, val, &oldval) == 1)
  398. env->ir[0] = val;
  399. break;
  400. case 0x0000003E:
  401. /* WTINT */
  402. break;
  403. case 0x0000003F:
  404. /* MFPR_WHAMI */
  405. if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
  406. env->ir[0] = val;
  407. break;
  408. case 0x00000080:
  409. /* BPT */
  410. /* REQUIRED */
  411. break;
  412. case 0x00000081:
  413. /* BUGCHK */
  414. /* REQUIRED */
  415. break;
  416. case 0x00000082:
  417. /* CHME */
  418. break;
  419. case 0x00000083:
  420. /* CHMK */
  421. break;
  422. case 0x00000084:
  423. /* CHMS */
  424. break;
  425. case 0x00000085:
  426. /* CHMU */
  427. break;
  428. case 0x00000086:
  429. /* IMB */
  430. /* REQUIRED */
  431. /* Implemented as no-op */
  432. break;
  433. case 0x00000087:
  434. /* INSQHIL */
  435. break;
  436. case 0x00000088:
  437. /* INSQTIL */
  438. break;
  439. case 0x00000089:
  440. /* INSQHIQ */
  441. break;
  442. case 0x0000008A:
  443. /* INSQTIQ */
  444. break;
  445. case 0x0000008B:
  446. /* INSQUEL */
  447. break;
  448. case 0x0000008C:
  449. /* INSQUEQ */
  450. break;
  451. case 0x0000008D:
  452. /* INSQUEL/D */
  453. break;
  454. case 0x0000008E:
  455. /* INSQUEQ/D */
  456. break;
  457. case 0x0000008F:
  458. /* PROBER */
  459. break;
  460. case 0x00000090:
  461. /* PROBEW */
  462. break;
  463. case 0x00000091:
  464. /* RD_PS */
  465. break;
  466. case 0x00000092:
  467. /* REI */
  468. break;
  469. case 0x00000093:
  470. /* REMQHIL */
  471. break;
  472. case 0x00000094:
  473. /* REMQTIL */
  474. break;
  475. case 0x00000095:
  476. /* REMQHIQ */
  477. break;
  478. case 0x00000096:
  479. /* REMQTIQ */
  480. break;
  481. case 0x00000097:
  482. /* REMQUEL */
  483. break;
  484. case 0x00000098:
  485. /* REMQUEQ */
  486. break;
  487. case 0x00000099:
  488. /* REMQUEL/D */
  489. break;
  490. case 0x0000009A:
  491. /* REMQUEQ/D */
  492. break;
  493. case 0x0000009B:
  494. /* SWASTEN */
  495. break;
  496. case 0x0000009C:
  497. /* WR_PS_SW */
  498. break;
  499. case 0x0000009D:
  500. /* RSCC */
  501. break;
  502. case 0x0000009E:
  503. /* READ_UNQ */
  504. /* REQUIRED */
  505. break;
  506. case 0x0000009F:
  507. /* WRITE_UNQ */
  508. /* REQUIRED */
  509. break;
  510. case 0x000000A0:
  511. /* AMOVRR */
  512. break;
  513. case 0x000000A1:
  514. /* AMOVRM */
  515. break;
  516. case 0x000000A2:
  517. /* INSQHILR */
  518. break;
  519. case 0x000000A3:
  520. /* INSQTILR */
  521. break;
  522. case 0x000000A4:
  523. /* INSQHIQR */
  524. break;
  525. case 0x000000A5:
  526. /* INSQTIQR */
  527. break;
  528. case 0x000000A6:
  529. /* REMQHILR */
  530. break;
  531. case 0x000000A7:
  532. /* REMQTILR */
  533. break;
  534. case 0x000000A8:
  535. /* REMQHIQR */
  536. break;
  537. case 0x000000A9:
  538. /* REMQTIQR */
  539. break;
  540. case 0x000000AA:
  541. /* GENTRAP */
  542. /* REQUIRED */
  543. break;
  544. case 0x000000AE:
  545. /* CLRFEN */
  546. break;
  547. default:
  548. break;
  549. }
  550. }
  551. static void pal_unix_call (CPUState *env, uint32_t palcode)
  552. {
  553. uint64_t palid, val, oldval;
  554. if (palcode < 0x00000080) {
  555. /* Privileged palcodes */
  556. if (!(env->ps >> 3)) {
  557. /* TODO: generate privilege exception */
  558. }
  559. }
  560. switch (palcode) {
  561. case 0x00000000:
  562. /* HALT */
  563. /* REQUIRED */
  564. break;
  565. case 0x00000001:
  566. /* CFLUSH */
  567. break;
  568. case 0x00000002:
  569. /* DRAINA */
  570. /* REQUIRED */
  571. /* Implemented as no-op */
  572. break;
  573. case 0x00000009:
  574. /* CSERVE */
  575. /* REQUIRED */
  576. break;
  577. case 0x0000000A:
  578. /* SWPPAL */
  579. /* REQUIRED */
  580. palid = env->ir[16];
  581. do_swappal(env, palid);
  582. break;
  583. case 0x0000000D:
  584. /* WRIPIR */
  585. val = env->ir[16];
  586. if (cpu_alpha_mtpr(env, IPR_IPIR, val, &oldval) == 1)
  587. env->ir[0] = val;
  588. break;
  589. case 0x00000010:
  590. /* RDMCES */
  591. if (cpu_alpha_mfpr(env, IPR_MCES, &val) == 0)
  592. env->ir[0] = val;
  593. break;
  594. case 0x00000011:
  595. /* WRMCES */
  596. val = env->ir[16];
  597. if (cpu_alpha_mtpr(env, IPR_MCES, val, &oldval) == 1)
  598. env->ir[0] = val;
  599. break;
  600. case 0x0000002B:
  601. /* WRFEN */
  602. val = env->ir[16];
  603. if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
  604. env->ir[0] = val;
  605. break;
  606. case 0x0000002D:
  607. /* WRVPTPTR */
  608. break;
  609. case 0x00000030:
  610. /* SWPCTX */
  611. break;
  612. case 0x00000031:
  613. /* WRVAL */
  614. break;
  615. case 0x00000032:
  616. /* RDVAL */
  617. break;
  618. case 0x00000033:
  619. /* TBI */
  620. val = env->ir[16];
  621. if (cpu_alpha_mtpr(env, IPR_TBIS, val, &oldval) == 1)
  622. env->ir[0] = val;
  623. break;
  624. case 0x00000034:
  625. /* WRENT */
  626. break;
  627. case 0x00000035:
  628. /* SWPIPL */
  629. break;
  630. case 0x00000036:
  631. /* RDPS */
  632. break;
  633. case 0x00000037:
  634. /* WRKGP */
  635. break;
  636. case 0x00000038:
  637. /* WRUSP */
  638. val = env->ir[16];
  639. if (cpu_alpha_mtpr(env, IPR_USP, val, &oldval) == 1)
  640. env->ir[0] = val;
  641. break;
  642. case 0x00000039:
  643. /* WRPERFMON */
  644. val = env->ir[16];
  645. if (cpu_alpha_mtpr(env, IPR_PERFMON, val, &oldval) == 1)
  646. env->ir[0] = val;
  647. break;
  648. case 0x0000003A:
  649. /* RDUSP */
  650. if (cpu_alpha_mfpr(env, IPR_USP, &val) == 0)
  651. env->ir[0] = val;
  652. break;
  653. case 0x0000003C:
  654. /* WHAMI */
  655. if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
  656. env->ir[0] = val;
  657. break;
  658. case 0x0000003D:
  659. /* RETSYS */
  660. break;
  661. case 0x0000003E:
  662. /* WTINT */
  663. break;
  664. case 0x0000003F:
  665. /* RTI */
  666. if (cpu_alpha_mfpr(env, IPR_WHAMI, &val) == 0)
  667. env->ir[0] = val;
  668. break;
  669. case 0x00000080:
  670. /* BPT */
  671. /* REQUIRED */
  672. break;
  673. case 0x00000081:
  674. /* BUGCHK */
  675. /* REQUIRED */
  676. break;
  677. case 0x00000083:
  678. /* CALLSYS */
  679. break;
  680. case 0x00000086:
  681. /* IMB */
  682. /* REQUIRED */
  683. /* Implemented as no-op */
  684. break;
  685. case 0x00000092:
  686. /* URTI */
  687. break;
  688. case 0x0000009E:
  689. /* RDUNIQUE */
  690. /* REQUIRED */
  691. break;
  692. case 0x0000009F:
  693. /* WRUNIQUE */
  694. /* REQUIRED */
  695. break;
  696. case 0x000000AA:
  697. /* GENTRAP */
  698. /* REQUIRED */
  699. break;
  700. case 0x000000AE:
  701. /* CLRFEN */
  702. break;
  703. default:
  704. break;
  705. }
  706. }
  707. void call_pal (CPUState *env)
  708. {
  709. pal_handler_t *pal_handler = env->pal_handler;
  710. switch (env->exception_index) {
  711. case EXCP_RESET:
  712. (*pal_handler->reset)(env);
  713. break;
  714. case EXCP_MCHK:
  715. (*pal_handler->machine_check)(env);
  716. break;
  717. case EXCP_ARITH:
  718. (*pal_handler->arithmetic)(env);
  719. break;
  720. case EXCP_INTERRUPT:
  721. (*pal_handler->interrupt)(env);
  722. break;
  723. case EXCP_DFAULT:
  724. (*pal_handler->dfault)(env);
  725. break;
  726. case EXCP_DTB_MISS_PAL:
  727. (*pal_handler->dtb_miss_pal)(env);
  728. break;
  729. case EXCP_DTB_MISS_NATIVE:
  730. (*pal_handler->dtb_miss_native)(env);
  731. break;
  732. case EXCP_UNALIGN:
  733. (*pal_handler->unalign)(env);
  734. break;
  735. case EXCP_ITB_MISS:
  736. (*pal_handler->itb_miss)(env);
  737. break;
  738. case EXCP_ITB_ACV:
  739. (*pal_handler->itb_acv)(env);
  740. break;
  741. case EXCP_OPCDEC:
  742. (*pal_handler->opcdec)(env);
  743. break;
  744. case EXCP_FEN:
  745. (*pal_handler->fen)(env);
  746. break;
  747. default:
  748. if (env->exception_index >= EXCP_CALL_PAL &&
  749. env->exception_index < EXCP_CALL_PALP) {
  750. /* Unprivileged PAL call */
  751. (*pal_handler->call_pal)
  752. (env, (env->exception_index - EXCP_CALL_PAL) >> 6);
  753. } else if (env->exception_index >= EXCP_CALL_PALP &&
  754. env->exception_index < EXCP_CALL_PALE) {
  755. /* Privileged PAL call */
  756. (*pal_handler->call_pal)
  757. (env, ((env->exception_index - EXCP_CALL_PALP) >> 6) + 0x80);
  758. } else {
  759. /* Should never happen */
  760. }
  761. break;
  762. }
  763. env->ipr[IPR_EXC_ADDR] &= ~1;
  764. }
  765. void pal_init (CPUState *env)
  766. {
  767. do_swappal(env, 0);
  768. }
  769. #if 0
  770. static uint64_t get_ptebase (CPUState *env, uint64_t vaddr)
  771. {
  772. uint64_t virbnd, ptbr;
  773. if ((env->features & FEATURE_VIRBND)) {
  774. cpu_alpha_mfpr(env, IPR_VIRBND, &virbnd);
  775. if (vaddr >= virbnd)
  776. cpu_alpha_mfpr(env, IPR_SYSPTBR, &ptbr);
  777. else
  778. cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
  779. } else {
  780. cpu_alpha_mfpr(env, IPR_PTBR, &ptbr);
  781. }
  782. return ptbr;
  783. }
  784. static int get_page_bits (CPUState *env)
  785. {
  786. /* XXX */
  787. return 13;
  788. }
  789. static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
  790. uint64_t ptebase, int page_bits, uint64_t level,
  791. int mmu_idx, int rw)
  792. {
  793. uint64_t pteaddr, pte, pfn;
  794. uint8_t gh;
  795. int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
  796. /* XXX: TOFIX */
  797. is_user = mmu_idx == MMU_USER_IDX;
  798. pteaddr = (ptebase << page_bits) + (8 * level);
  799. pte = ldq_raw(pteaddr);
  800. /* Decode all interresting PTE fields */
  801. pfn = pte >> 32;
  802. uwe = (pte >> 13) & 1;
  803. kwe = (pte >> 12) & 1;
  804. ure = (pte >> 9) & 1;
  805. kre = (pte >> 8) & 1;
  806. gh = (pte >> 5) & 3;
  807. foE = (pte >> 3) & 1;
  808. foW = (pte >> 2) & 1;
  809. foR = (pte >> 1) & 1;
  810. v = pte & 1;
  811. ret = 0;
  812. if (!v)
  813. ret = 0x1;
  814. /* Check access rights */
  815. ar = 0;
  816. if (is_user) {
  817. if (ure)
  818. ar |= PAGE_READ;
  819. if (uwe)
  820. ar |= PAGE_WRITE;
  821. if (rw == 1 && !uwe)
  822. ret |= 0x2;
  823. if (rw != 1 && !ure)
  824. ret |= 0x2;
  825. } else {
  826. if (kre)
  827. ar |= PAGE_READ;
  828. if (kwe)
  829. ar |= PAGE_WRITE;
  830. if (rw == 1 && !kwe)
  831. ret |= 0x2;
  832. if (rw != 1 && !kre)
  833. ret |= 0x2;
  834. }
  835. if (rw == 0 && foR)
  836. ret |= 0x4;
  837. if (rw == 2 && foE)
  838. ret |= 0x8;
  839. if (rw == 1 && foW)
  840. ret |= 0xC;
  841. *pfnp = pfn;
  842. if (zbitsp != NULL)
  843. *zbitsp = page_bits + (3 * gh);
  844. if (protp != NULL)
  845. *protp = ar;
  846. return ret;
  847. }
  848. static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
  849. uint64_t ptebase, int page_bits,
  850. uint64_t vaddr, int mmu_idx, int rw)
  851. {
  852. uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
  853. int lvl_bits, ret;
  854. page_mask = (1ULL << page_bits) - 1ULL;
  855. lvl_bits = page_bits - 3;
  856. lvl_mask = (1ULL << lvl_bits) - 1ULL;
  857. level3 = (vaddr >> page_bits) & lvl_mask;
  858. level2 = (vaddr >> (page_bits + lvl_bits)) & lvl_mask;
  859. level1 = (vaddr >> (page_bits + (2 * lvl_bits))) & lvl_mask;
  860. /* Level 1 PTE */
  861. ret = get_pte(&pfn, NULL, NULL, ptebase, page_bits, level1, 0, 0);
  862. switch (ret) {
  863. case 3:
  864. /* Access violation */
  865. return 2;
  866. case 2:
  867. /* translation not valid */
  868. return 1;
  869. default:
  870. /* OK */
  871. break;
  872. }
  873. /* Level 2 PTE */
  874. ret = get_pte(&pfn, NULL, NULL, pfn, page_bits, level2, 0, 0);
  875. switch (ret) {
  876. case 3:
  877. /* Access violation */
  878. return 2;
  879. case 2:
  880. /* translation not valid */
  881. return 1;
  882. default:
  883. /* OK */
  884. break;
  885. }
  886. /* Level 3 PTE */
  887. ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
  888. if (ret & 0x1) {
  889. /* Translation not valid */
  890. ret = 1;
  891. } else if (ret & 2) {
  892. /* Access violation */
  893. ret = 2;
  894. } else {
  895. switch (ret & 0xC) {
  896. case 0:
  897. /* OK */
  898. ret = 0;
  899. break;
  900. case 0x4:
  901. /* Fault on read */
  902. ret = 3;
  903. break;
  904. case 0x8:
  905. /* Fault on execute */
  906. ret = 4;
  907. break;
  908. case 0xC:
  909. /* Fault on write */
  910. ret = 5;
  911. break;
  912. }
  913. }
  914. *paddr = (pfn << page_bits) | (vaddr & page_mask);
  915. return 0;
  916. }
  917. static int virtual_to_physical (CPUState *env, uint64_t *physp,
  918. int *zbitsp, int *protp,
  919. uint64_t virtual, int mmu_idx, int rw)
  920. {
  921. uint64_t sva, ptebase;
  922. int seg, page_bits, ret;
  923. sva = ((int64_t)(virtual << (64 - VA_BITS))) >> (64 - VA_BITS);
  924. if (sva != virtual)
  925. seg = -1;
  926. else
  927. seg = sva >> (VA_BITS - 2);
  928. virtual &= ~(0xFFFFFC0000000000ULL << (VA_BITS - 43));
  929. ptebase = get_ptebase(env, virtual);
  930. page_bits = get_page_bits(env);
  931. ret = 0;
  932. switch (seg) {
  933. case 0:
  934. /* seg1: 3 levels of PTE */
  935. ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
  936. virtual, mmu_idx, rw);
  937. break;
  938. case 1:
  939. /* seg1: 2 levels of PTE */
  940. ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
  941. virtual, mmu_idx, rw);
  942. break;
  943. case 2:
  944. /* kernel segment */
  945. if (mmu_idx != 0) {
  946. ret = 2;
  947. } else {
  948. *physp = virtual;
  949. }
  950. break;
  951. case 3:
  952. /* seg1: TB mapped */
  953. ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
  954. virtual, mmu_idx, rw);
  955. break;
  956. default:
  957. ret = 1;
  958. break;
  959. }
  960. return ret;
  961. }
  962. /* XXX: code provision */
  963. int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
  964. int mmu_idx, int is_softmmu)
  965. {
  966. uint64_t physical, page_size, end;
  967. int prot, zbits, ret;
  968. #if defined(CONFIG_USER_ONLY)
  969. ret = 2;
  970. #else
  971. ret = virtual_to_physical(env, &physical, &zbits, &prot,
  972. address, mmu_idx, rw);
  973. #endif
  974. switch (ret) {
  975. case 0:
  976. /* No fault */
  977. page_size = 1ULL << zbits;
  978. address &= ~(page_size - 1);
  979. for (end = physical + page_size; physical < end; physical += 0x1000) {
  980. ret = tlb_set_page(env, address, physical, prot,
  981. mmu_idx, is_softmmu);
  982. address += 0x1000;
  983. }
  984. break;
  985. #if 0
  986. case 1:
  987. env->exception_index = EXCP_DFAULT;
  988. env->ipr[IPR_EXC_ADDR] = address;
  989. ret = 1;
  990. break;
  991. case 2:
  992. env->exception_index = EXCP_ACCESS_VIOLATION;
  993. env->ipr[IPR_EXC_ADDR] = address;
  994. ret = 1;
  995. break;
  996. case 3:
  997. env->exception_index = EXCP_FAULT_ON_READ;
  998. env->ipr[IPR_EXC_ADDR] = address;
  999. ret = 1;
  1000. break;
  1001. case 4:
  1002. env->exception_index = EXCP_FAULT_ON_EXECUTE;
  1003. env->ipr[IPR_EXC_ADDR] = address;
  1004. ret = 1;
  1005. case 5:
  1006. env->exception_index = EXCP_FAULT_ON_WRITE;
  1007. env->ipr[IPR_EXC_ADDR] = address;
  1008. ret = 1;
  1009. #endif
  1010. default:
  1011. /* Should never happen */
  1012. env->exception_index = EXCP_MCHK;
  1013. env->ipr[IPR_EXC_ADDR] = address;
  1014. ret = 1;
  1015. break;
  1016. }
  1017. return ret;
  1018. }
  1019. #endif
  1020. #else /* !defined (CONFIG_USER_ONLY) */
  1021. void pal_init (CPUState *env)
  1022. {
  1023. }
  1024. void call_pal (CPUState *env, int palcode)
  1025. {
  1026. target_long ret;
  1027. qemu_log("%s: palcode %02x\n", __func__, palcode);
  1028. switch (palcode) {
  1029. case 0x83:
  1030. /* CALLSYS */
  1031. qemu_log("CALLSYS n " TARGET_FMT_ld "\n", env->ir[0]);
  1032. ret = do_syscall(env, env->ir[IR_V0], env->ir[IR_A0], env->ir[IR_A1],
  1033. env->ir[IR_A2], env->ir[IR_A3], env->ir[IR_A4],
  1034. env->ir[IR_A5]);
  1035. if (ret >= 0) {
  1036. env->ir[IR_A3] = 0;
  1037. env->ir[IR_V0] = ret;
  1038. } else {
  1039. env->ir[IR_A3] = 1;
  1040. env->ir[IR_V0] = -ret;
  1041. }
  1042. break;
  1043. case 0x9E:
  1044. /* RDUNIQUE */
  1045. env->ir[IR_V0] = env->unique;
  1046. qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
  1047. break;
  1048. case 0x9F:
  1049. /* WRUNIQUE */
  1050. env->unique = env->ir[IR_A0];
  1051. qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->unique);
  1052. break;
  1053. default:
  1054. qemu_log("%s: unhandled palcode %02x\n",
  1055. __func__, palcode);
  1056. exit(1);
  1057. }
  1058. }
  1059. #endif