Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4065 lines
118 KiB

  1. /*** ia64_reg.c - processor-specific register structures
  2. *
  3. * Copyright <C> 1990-2001, Microsoft Corporation
  4. * Copyright <C> 1995, Intel Corporation
  5. *
  6. * Purpose:
  7. * Structures used to parse and access register and flag
  8. * fields.
  9. *
  10. * Revision History:
  11. *
  12. * [-] 10-Jan-1995 HC Modified for IA64. All registers are 64-bit
  13. * except floating point registers are 128-bit.
  14. * [-] 01-Jul-1990 Richk Created.
  15. *
  16. *************************************************************************/
  17. #include "ntsdp.hpp"
  18. #include "ia64_dis.h"
  19. // See Get/SetRegVal comments in machine.hpp.
  20. #define RegValError Do_not_use_GetSetRegVal_in_machine_implementations
  21. #define GetRegVal(index, val) RegValError
  22. #define GetRegVal32(index) RegValError
  23. #define GetRegVal64(index) RegValError
  24. #define SetRegVal(index, val) RegValError
  25. #define SetRegVal32(index, val) RegValError
  26. #define SetRegVal64(index, val) RegValError
  27. // TBD
  28. #define IS_FLOATING_SAVED(Register) ((SAVED_FLOATING_MASK >> Register) & 1L)
  29. #define IS_INTEGER_SAVED(Register) ((SAVED_INTEGER_MASK >> Register) & 1L)
  30. //
  31. // Define saved register masks.
  32. //
  33. #define SAVED_FLOATING_MASK 0xfff00000 // saved floating registers
  34. #define SAVED_INTEGER_MASK 0xf3ffff02 // saved integer registers
  35. //
  36. // Number of Data Breakpoints available under IA64
  37. //
  38. // XXX olegk - increase to 4 in future
  39. // (and then remove appropriate check at MapDbgSlotIa64ToX86)
  40. #define IA64_REG_MAX_DATA_BREAKPOINTS 2
  41. //
  42. // This parallels ntreg.h. Symbol assignment models ksia64.h
  43. //
  44. CHAR szDBI0[] = "dbi0";
  45. CHAR szDBI1[] = "dbi1";
  46. CHAR szDBI2[] = "dbi2";
  47. CHAR szDBI3[] = "dbi3";
  48. CHAR szDBI4[] = "dbi4";
  49. CHAR szDBI5[] = "dbi5";
  50. CHAR szDBI6[] = "dbi6";
  51. CHAR szDBI7[] = "dbi7";
  52. CHAR szDBD0[] = "dbd0";
  53. CHAR szDBD1[] = "dbd1";
  54. CHAR szDBD2[] = "dbd2";
  55. CHAR szDBD3[] = "dbd3";
  56. CHAR szDBD4[] = "dbd4";
  57. CHAR szDBD5[] = "dbd5";
  58. CHAR szDBD6[] = "dbd6";
  59. CHAR szDBD7[] = "dbd7";
  60. CHAR szF32[] = "f32"; // High floating point temporary (scratch) registers
  61. CHAR szF33[] = "f33";
  62. CHAR szF34[] = "f34";
  63. CHAR szF35[] = "f35";
  64. CHAR szF36[] = "f36";
  65. CHAR szF37[] = "f37";
  66. CHAR szF38[] = "f38";
  67. CHAR szF39[] = "f39";
  68. CHAR szF40[] = "f40";
  69. CHAR szF41[] = "f41";
  70. CHAR szF42[] = "f42";
  71. CHAR szF43[] = "f43";
  72. CHAR szF44[] = "f44";
  73. CHAR szF45[] = "f45";
  74. CHAR szF46[] = "f46";
  75. CHAR szF47[] = "f47";
  76. CHAR szF48[] = "f48";
  77. CHAR szF49[] = "f49";
  78. CHAR szF50[] = "f50";
  79. CHAR szF51[] = "f51";
  80. CHAR szF52[] = "f52";
  81. CHAR szF53[] = "f53";
  82. CHAR szF54[] = "f54";
  83. CHAR szF55[] = "f55";
  84. CHAR szF56[] = "f56";
  85. CHAR szF57[] = "f57";
  86. CHAR szF58[] = "f58";
  87. CHAR szF59[] = "f59";
  88. CHAR szF60[] = "f60";
  89. CHAR szF61[] = "f61";
  90. CHAR szF62[] = "f62";
  91. CHAR szF63[] = "f63";
  92. CHAR szF64[] = "f64";
  93. CHAR szF65[] = "f65";
  94. CHAR szF66[] = "f66";
  95. CHAR szF67[] = "f67";
  96. CHAR szF68[] = "f68";
  97. CHAR szF69[] = "f69";
  98. CHAR szF70[] = "f70";
  99. CHAR szF71[] = "f71";
  100. CHAR szF72[] = "f72";
  101. CHAR szF73[] = "f73";
  102. CHAR szF74[] = "f74";
  103. CHAR szF75[] = "f75";
  104. CHAR szF76[] = "f76";
  105. CHAR szF77[] = "f77";
  106. CHAR szF78[] = "f78";
  107. CHAR szF79[] = "f79";
  108. CHAR szF80[] = "f80";
  109. CHAR szF81[] = "f81";
  110. CHAR szF82[] = "f82";
  111. CHAR szF83[] = "f83";
  112. CHAR szF84[] = "f84";
  113. CHAR szF85[] = "f85";
  114. CHAR szF86[] = "f86";
  115. CHAR szF87[] = "f87";
  116. CHAR szF88[] = "f88";
  117. CHAR szF89[] = "f89";
  118. CHAR szF90[] = "f90";
  119. CHAR szF91[] = "f91";
  120. CHAR szF92[] = "f92";
  121. CHAR szF93[] = "f93";
  122. CHAR szF94[] = "f94";
  123. CHAR szF95[] = "f95";
  124. CHAR szF96[] = "f96";
  125. CHAR szF97[] = "f97";
  126. CHAR szF98[] = "f98";
  127. CHAR szF99[] = "f99";
  128. CHAR szF100[] = "f100";
  129. CHAR szF101[] = "f101";
  130. CHAR szF102[] = "f102";
  131. CHAR szF103[] = "f103";
  132. CHAR szF104[] = "f104";
  133. CHAR szF105[] = "f105";
  134. CHAR szF106[] = "f106";
  135. CHAR szF107[] = "f107";
  136. CHAR szF108[] = "f108";
  137. CHAR szF109[] = "f109";
  138. CHAR szF110[] = "f110";
  139. CHAR szF111[] = "f111";
  140. CHAR szF112[] = "f112";
  141. CHAR szF113[] = "f113";
  142. CHAR szF114[] = "f114";
  143. CHAR szF115[] = "f115";
  144. CHAR szF116[] = "f116";
  145. CHAR szF117[] = "f117";
  146. CHAR szF118[] = "f118";
  147. CHAR szF119[] = "f119";
  148. CHAR szF120[] = "f120";
  149. CHAR szF121[] = "f121";
  150. CHAR szF122[] = "f122";
  151. CHAR szF123[] = "f123";
  152. CHAR szF124[] = "f124";
  153. CHAR szF125[] = "f125";
  154. CHAR szF126[] = "f126";
  155. CHAR szF127[] = "f127";
  156. CHAR szFPSR[] = "fpsr";
  157. CHAR szFSR[] = "fsr";
  158. CHAR szFIR[] = "fir";
  159. CHAR szFDR[] = "fdr";
  160. CHAR szFCR[] = "fcr";
  161. CHAR szGP[] = "gp"; // global pointer
  162. CHAR szSP[] = "sp"; // stack pointer
  163. CHAR szR32[] = "r32";
  164. CHAR szR33[] = "r33";
  165. CHAR szR34[] = "r34";
  166. CHAR szR35[] = "r35";
  167. CHAR szR36[] = "r36";
  168. CHAR szR37[] = "r37";
  169. CHAR szR38[] = "r38";
  170. CHAR szR39[] = "r39";
  171. CHAR szR40[] = "r40";
  172. CHAR szR41[] = "r41";
  173. CHAR szR42[] = "r42";
  174. CHAR szR43[] = "r43";
  175. CHAR szR44[] = "r44";
  176. CHAR szR45[] = "r45";
  177. CHAR szR46[] = "r46";
  178. CHAR szR47[] = "r47";
  179. CHAR szR48[] = "r48";
  180. CHAR szR49[] = "r49";
  181. CHAR szR50[] = "r50";
  182. CHAR szR51[] = "r51";
  183. CHAR szR52[] = "r52";
  184. CHAR szR53[] = "r53";
  185. CHAR szR54[] = "r54";
  186. CHAR szR55[] = "r55";
  187. CHAR szR56[] = "r56";
  188. CHAR szR57[] = "r57";
  189. CHAR szR58[] = "r58";
  190. CHAR szR59[] = "r59";
  191. CHAR szR60[] = "r60";
  192. CHAR szR61[] = "r61";
  193. CHAR szR62[] = "r62";
  194. CHAR szR63[] = "r63";
  195. CHAR szR64[] = "r64";
  196. CHAR szR65[] = "r65";
  197. CHAR szR66[] = "r66";
  198. CHAR szR67[] = "r67";
  199. CHAR szR68[] = "r68";
  200. CHAR szR69[] = "r69";
  201. CHAR szR70[] = "r70";
  202. CHAR szR71[] = "r71";
  203. CHAR szR72[] = "r72";
  204. CHAR szR73[] = "r73";
  205. CHAR szR74[] = "r74";
  206. CHAR szR75[] = "r75";
  207. CHAR szR76[] = "r76";
  208. CHAR szR77[] = "r77";
  209. CHAR szR78[] = "r78";
  210. CHAR szR79[] = "r79";
  211. CHAR szR80[] = "r80";
  212. CHAR szR81[] = "r81";
  213. CHAR szR82[] = "r82";
  214. CHAR szR83[] = "r83";
  215. CHAR szR84[] = "r84";
  216. CHAR szR85[] = "r85";
  217. CHAR szR86[] = "r86";
  218. CHAR szR87[] = "r87";
  219. CHAR szR88[] = "r88";
  220. CHAR szR89[] = "r89";
  221. CHAR szR90[] = "r90";
  222. CHAR szR91[] = "r91";
  223. CHAR szR92[] = "r92";
  224. CHAR szR93[] = "r93";
  225. CHAR szR94[] = "r94";
  226. CHAR szR95[] = "r95";
  227. CHAR szR96[] = "r96";
  228. CHAR szR97[] = "r97";
  229. CHAR szR98[] = "r98";
  230. CHAR szR99[] = "r99";
  231. CHAR szR100[] = "r100";
  232. CHAR szR101[] = "r101";
  233. CHAR szR102[] = "r102";
  234. CHAR szR103[] = "r103";
  235. CHAR szR104[] = "r104";
  236. CHAR szR105[] = "r105";
  237. CHAR szR106[] = "r106";
  238. CHAR szR107[] = "r107";
  239. CHAR szR108[] = "r108";
  240. CHAR szR109[] = "r109";
  241. CHAR szR110[] = "r110";
  242. CHAR szR111[] = "r111";
  243. CHAR szR112[] = "r112";
  244. CHAR szR113[] = "r113";
  245. CHAR szR114[] = "r114";
  246. CHAR szR115[] = "r115";
  247. CHAR szR116[] = "r116";
  248. CHAR szR117[] = "r117";
  249. CHAR szR118[] = "r118";
  250. CHAR szR119[] = "r119";
  251. CHAR szR120[] = "r120";
  252. CHAR szR121[] = "r121";
  253. CHAR szR122[] = "r122";
  254. CHAR szR123[] = "r123";
  255. CHAR szR124[] = "r124";
  256. CHAR szR125[] = "r125";
  257. CHAR szR126[] = "r126";
  258. CHAR szR127[] = "r127";
  259. CHAR szINTNATS[] = "intnats";
  260. CHAR szPREDS[] = "preds";
  261. CHAR szB0[] = "b0"; // branch return pointer
  262. CHAR szB1[] = "b1"; // branch saved (preserved)
  263. CHAR szB2[] = "b2";
  264. CHAR szB3[] = "b3";
  265. CHAR szB4[] = "b4";
  266. CHAR szB5[] = "b5";
  267. CHAR szB6[] = "b6"; // branch temporary (scratch) registers
  268. CHAR szB7[] = "b7";
  269. CHAR szCSD[] = "csd"; // iA32 CS descriptor
  270. CHAR szSSD[] = "ssd"; // iA32 SS descriptor
  271. CHAR szAPUNAT[] = "unat";
  272. CHAR szAPLC[] = "lc";
  273. CHAR szAPEC[] = "ec";
  274. CHAR szAPCCV[] = "ccv";
  275. CHAR szAPDCR[] = "dcr";
  276. CHAR szRSPFS[] = "pfs";
  277. CHAR szRSBSP[] = "bsp";
  278. CHAR szRSBSPSTORE[] = "bspstore";
  279. CHAR szRSRSC[] = "rsc";
  280. CHAR szRSRNAT[] = "rnat";
  281. CHAR szEFLAG[] = "eflag"; // iA32 Eflag
  282. CHAR szCFLAG[] = "cflag"; // iA32 Cflag
  283. CHAR szSTIPSR[] = "ipsr";
  284. CHAR szSTIIP[] = "iip";
  285. CHAR szSTIFS[] = "ifs";
  286. CHAR szKDBI0[] = "kdbi0";
  287. CHAR szKDBI1[] = "kdbi1";
  288. CHAR szKDBI2[] = "kdbi2";
  289. CHAR szKDBI3[] = "kdbi3";
  290. CHAR szKDBI4[] = "kdbi4";
  291. CHAR szKDBI5[] = "kdbi5";
  292. CHAR szKDBI6[] = "kdbi6";
  293. CHAR szKDBI7[] = "kdbi7";
  294. CHAR szKDBD0[] = "kdbd0";
  295. CHAR szKDBD1[] = "kdbd1";
  296. CHAR szKDBD2[] = "kdbd2";
  297. CHAR szKDBD3[] = "kdbd3";
  298. CHAR szKDBD4[] = "kdbd4";
  299. CHAR szKDBD5[] = "kdbd5";
  300. CHAR szKDBD6[] = "kdbd6";
  301. CHAR szKDBD7[] = "kdbd7";
  302. CHAR szKPFC0[] = "kpfc0";
  303. CHAR szKPFC1[] = "kpfc1";
  304. CHAR szKPFC2[] = "kpfc2";
  305. CHAR szKPFC3[] = "kpfc3";
  306. CHAR szKPFC4[] = "kpfc4";
  307. CHAR szKPFC5[] = "kpfc5";
  308. CHAR szKPFC6[] = "kpfc6";
  309. CHAR szKPFC7[] = "kpfc7";
  310. CHAR szKPFD0[] = "kpfd0";
  311. CHAR szKPFD1[] = "kpfd1";
  312. CHAR szKPFD2[] = "kpfd2";
  313. CHAR szKPFD3[] = "kpfd3";
  314. CHAR szKPFD4[] = "kpfd4";
  315. CHAR szKPFD5[] = "kpfd5";
  316. CHAR szKPFD6[] = "kpfd6";
  317. CHAR szKPFD7[] = "kpfd7";
  318. CHAR szH16[] = "h16"; // kernel bank shadow (hidden) registers
  319. CHAR szH17[] = "h17";
  320. CHAR szH18[] = "h18";
  321. CHAR szH19[] = "h19";
  322. CHAR szH20[] = "h20";
  323. CHAR szH21[] = "h21";
  324. CHAR szH22[] = "h22";
  325. CHAR szH23[] = "h23";
  326. CHAR szH24[] = "h24";
  327. CHAR szH25[] = "h25";
  328. CHAR szH26[] = "h26";
  329. CHAR szH27[] = "h27";
  330. CHAR szH28[] = "h28";
  331. CHAR szH29[] = "h29";
  332. CHAR szH30[] = "h30";
  333. CHAR szH31[] = "h31";
  334. CHAR szACPUID0[] = "cpuid0";
  335. CHAR szACPUID1[] = "cpuid1";
  336. CHAR szACPUID2[] = "cpuid2";
  337. CHAR szACPUID3[] = "cpuid3";
  338. CHAR szACPUID4[] = "cpuid4";
  339. CHAR szACPUID5[] = "cpuid5";
  340. CHAR szACPUID6[] = "cpuid6";
  341. CHAR szACPUID7[] = "cpuid7";
  342. CHAR szAPKR0[] = "kr0";
  343. CHAR szAPKR1[] = "kr1";
  344. CHAR szAPKR2[] = "kr2";
  345. CHAR szAPKR3[] = "kr3";
  346. CHAR szAPKR4[] = "kr4";
  347. CHAR szAPKR5[] = "kr5";
  348. CHAR szAPKR6[] = "kr6";
  349. CHAR szAPKR7[] = "kr7";
  350. CHAR szAPITC[] = "itc";
  351. CHAR szAPITM[] = "itm";
  352. CHAR szAPIVA[] = "iva";
  353. CHAR szAPPTA[] = "pta";
  354. CHAR szAPGPTA[] = "apgta";
  355. CHAR szSTISR[] = "isr";
  356. CHAR szSTIDA[] = "ifa";
  357. CHAR szSTIDTR[] = "idtr";
  358. CHAR szSTIITR[] = "itir";
  359. CHAR szSTIIPA[] = "iipa";
  360. CHAR szSTIIM[] = "iim";
  361. CHAR szSTIHA[] = "iha";
  362. CHAR szSALID[] = "lid";
  363. CHAR szSAIVR[] = "ivr";
  364. CHAR szSATPR[] = "tpr";
  365. CHAR szSAEOI[] = "eoi";
  366. CHAR szSAIRR0[] = "irr0";
  367. CHAR szSAIRR1[] = "irr1";
  368. CHAR szSAIRR2[] = "irr2";
  369. CHAR szSAIRR3[] = "irr3";
  370. CHAR szSAITV[] = "itv";
  371. CHAR szSAPMV[] = "pmv";
  372. CHAR szSALRR0[] = "lrr0";
  373. CHAR szSALRR1[] = "lrr1";
  374. CHAR szSACMCV[] = "cmcv";
  375. CHAR szRR0[] = "rr0";
  376. CHAR szRR1[] = "rr1";
  377. CHAR szRR2[] = "rr2";
  378. CHAR szRR3[] = "rr3";
  379. CHAR szRR4[] = "rr4";
  380. CHAR szRR5[] = "rr5";
  381. CHAR szRR6[] = "rr6";
  382. CHAR szRR7[] = "rr7";
  383. CHAR szPKR0[] = "pkr0";
  384. CHAR szPKR1[] = "pkr1";
  385. CHAR szPKR2[] = "pkr2";
  386. CHAR szPKR3[] = "pkr3";
  387. CHAR szPKR4[] = "pkr4";
  388. CHAR szPKR5[] = "pkr5";
  389. CHAR szPKR6[] = "pkr6";
  390. CHAR szPKR7[] = "pkr7";
  391. CHAR szPKR8[] = "pkr8";
  392. CHAR szPKR9[] = "pkr9";
  393. CHAR szPKR10[] = "pkr10";
  394. CHAR szPKR11[] = "pkr11";
  395. CHAR szPKR12[] = "pkr12";
  396. CHAR szPKR13[] = "pkr13";
  397. CHAR szPKR14[] = "pkr14";
  398. CHAR szPKR15[] = "pkr15";
  399. CHAR szTRI0[] = "tri0";
  400. CHAR szTRI1[] = "tri1";
  401. CHAR szTRI2[] = "tri2";
  402. CHAR szTRI3[] = "tri3";
  403. CHAR szTRI4[] = "tri4";
  404. CHAR szTRI5[] = "tri5";
  405. CHAR szTRI6[] = "tri6";
  406. CHAR szTRI7[] = "tri7";
  407. CHAR szTRD0[] = "trd0";
  408. CHAR szTRD1[] = "trd1";
  409. CHAR szTRD2[] = "trd2";
  410. CHAR szTRD3[] = "trd3";
  411. CHAR szTRD4[] = "trd4";
  412. CHAR szTRD5[] = "trd5";
  413. CHAR szTRD6[] = "trd6";
  414. CHAR szTRD7[] = "trd7";
  415. CHAR szSMSR0[] = "SMSR0";
  416. CHAR szSMSR1[] = "SMSR1";
  417. CHAR szSMSR2[] = "SMSR2";
  418. CHAR szSMSR3[] = "SMSR3";
  419. CHAR szSMSR4[] = "SMSR4";
  420. CHAR szSMSR5[] = "SMSR5";
  421. CHAR szSMSR6[] = "SMSR6";
  422. CHAR szSMSR7[] = "SMSR7";
  423. // IPSR flags
  424. CHAR szIPSRBN[] = "ipsr.bn";
  425. CHAR szIPSRED[] = "ipsr.ed";
  426. CHAR szIPSRRI[] = "ipsr.ri";
  427. CHAR szIPSRSS[] = "ipsr.ss";
  428. CHAR szIPSRDD[] = "ipsr.dd";
  429. CHAR szIPSRDA[] = "ipsr.da";
  430. CHAR szIPSRID[] = "ipsr.id";
  431. CHAR szIPSRIT[] = "ipsr.it";
  432. CHAR szIPSRME[] = "ipsr.me";
  433. CHAR szIPSRIS[] = "ipsr.is";
  434. CHAR szIPSRCPL[] = "ipsr.cpl";
  435. CHAR szIPSRRT[] = "ipsr.rt";
  436. CHAR szIPSRTB[] = "ipsr.tb";
  437. CHAR szIPSRLP[] = "ipsr.lp";
  438. CHAR szIPSRDB[] = "ipsr.db";
  439. CHAR szIPSRSI[] = "ipsr.si";
  440. CHAR szIPSRDI[] = "ipsr.di";
  441. CHAR szIPSRPP[] = "ipsr.pp";
  442. CHAR szIPSRSP[] = "ipsr.sp";
  443. CHAR szIPSRDFH[] = "ipsr.dfh";
  444. CHAR szIPSRDFL[] = "ipsr.dfl";
  445. CHAR szIPSRDT[] = "ipsr.dt";
  446. CHAR szIPSRPK[] = "ipsr.pk";
  447. CHAR szIPSRI[] = "ipsr.i";
  448. CHAR szIPSRIC[] = "ipsr.ic";
  449. CHAR szIPSRAC[] = "ipsr.ac";
  450. CHAR szIPSRUP[] = "ipsr.up";
  451. CHAR szIPSRBE[] = "ipsr.be";
  452. CHAR szIPSROR[] = "ipsr.or";
  453. // FPSR flags
  454. CHAR szFPSRMDH[] = "fpsr.mdh";
  455. CHAR szFPSRMDL[] = "fpsr.mdl";
  456. CHAR szFPSRSF3[] = "fpsr.sf3";
  457. CHAR szFPSRSF2[] = "fpsr.sf2";
  458. CHAR szFPSRSF1[] = "fpsr.sf1";
  459. CHAR szFPSRSF0[] = "fpsr.sf0";
  460. CHAR szFPSRTRAPID[] = "fpsr.id";
  461. CHAR szFPSRTRAPUD[] = "fpsr.ud";
  462. CHAR szFPSRTRAPOD[] = "fpsr.od";
  463. CHAR szFPSRTRAPZD[] = "fpsr.zd";
  464. CHAR szFPSRTRAPDD[] = "fpsr.dd";
  465. CHAR szFPSRTRAPVD[] = "fpsr.vd";
  466. // Predicate registers
  467. //CHAR szPR0[] = "p0";
  468. CHAR szPR1[] = "p1";
  469. CHAR szPR2[] = "p2";
  470. CHAR szPR3[] = "p3";
  471. CHAR szPR4[] = "p4";
  472. CHAR szPR5[] = "p5";
  473. CHAR szPR6[] = "p6";
  474. CHAR szPR7[] = "p7";
  475. CHAR szPR8[] = "p8";
  476. CHAR szPR9[] = "p9";
  477. CHAR szPR10[] = "p10";
  478. CHAR szPR11[] = "p11";
  479. CHAR szPR12[] = "p12";
  480. CHAR szPR13[] = "p13";
  481. CHAR szPR14[] = "p14";
  482. CHAR szPR15[] = "p15";
  483. CHAR szPR16[] = "p16";
  484. CHAR szPR17[] = "p17";
  485. CHAR szPR18[] = "p18";
  486. CHAR szPR19[] = "p19";
  487. CHAR szPR20[] = "p20";
  488. CHAR szPR21[] = "p21";
  489. CHAR szPR22[] = "p22";
  490. CHAR szPR23[] = "p23";
  491. CHAR szPR24[] = "p24";
  492. CHAR szPR25[] = "p25";
  493. CHAR szPR26[] = "p26";
  494. CHAR szPR27[] = "p27";
  495. CHAR szPR28[] = "p28";
  496. CHAR szPR29[] = "p29";
  497. CHAR szPR30[] = "p30";
  498. CHAR szPR31[] = "p31";
  499. CHAR szPR32[] = "p32";
  500. CHAR szPR33[] = "p33";
  501. CHAR szPR34[] = "p34";
  502. CHAR szPR35[] = "p35";
  503. CHAR szPR36[] = "p36";
  504. CHAR szPR37[] = "p37";
  505. CHAR szPR38[] = "p38";
  506. CHAR szPR39[] = "p39";
  507. CHAR szPR40[] = "p40";
  508. CHAR szPR41[] = "p41";
  509. CHAR szPR42[] = "p42";
  510. CHAR szPR43[] = "p43";
  511. CHAR szPR44[] = "p44";
  512. CHAR szPR45[] = "p45";
  513. CHAR szPR46[] = "p46";
  514. CHAR szPR47[] = "p47";
  515. CHAR szPR48[] = "p48";
  516. CHAR szPR49[] = "p49";
  517. CHAR szPR50[] = "p50";
  518. CHAR szPR51[] = "p51";
  519. CHAR szPR52[] = "p52";
  520. CHAR szPR53[] = "p53";
  521. CHAR szPR54[] = "p54";
  522. CHAR szPR55[] = "p55";
  523. CHAR szPR56[] = "p56";
  524. CHAR szPR57[] = "p57";
  525. CHAR szPR58[] = "p58";
  526. CHAR szPR59[] = "p59";
  527. CHAR szPR60[] = "p60";
  528. CHAR szPR61[] = "p61";
  529. CHAR szPR62[] = "p62";
  530. CHAR szPR63[] = "p63";
  531. // Aliases: allow aliases to general purpose registers that are
  532. // known by more than one name, eg r12 = rsp.
  533. CHAR szR1GP[] = "r1";
  534. CHAR szR12SP[] = "r12";
  535. CHAR szRA[] = "ra";
  536. CHAR szRP[] = "rp";
  537. CHAR szRET0[] = "ret0";
  538. CHAR szRET1[] = "ret1";
  539. CHAR szRET2[] = "ret2";
  540. CHAR szRET3[] = "ret3";
  541. REGDEF IA64Regs[] =
  542. {
  543. szDBI0, REGDBI0, szDBI1, REGDBI1, szDBI2, REGDBI2, szDBI3, REGDBI3,
  544. szDBI4, REGDBI4, szDBI5, REGDBI5, szDBI6, REGDBI6, szDBI7, REGDBI7,
  545. szDBD0, REGDBD0, szDBD1, REGDBD1, szDBD2, REGDBD2, szDBD3, REGDBD3,
  546. szDBD4, REGDBD4, szDBD5, REGDBD5, szDBD6, REGDBD6, szDBD7, REGDBD7,
  547. // g_F0, FLTZERO, g_F1, FLTONE,
  548. g_F2, FLTS0, g_F3, FLTS1,
  549. g_F4, FLTS2, g_F5, FLTS3, g_F6, FLTT0, g_F7, FLTT1,
  550. g_F8, FLTT2, g_F9, FLTT3, g_F10, FLTT4, g_F11, FLTT5,
  551. g_F12, FLTT6, g_F13, FLTT7, g_F14, FLTT8, g_F15, FLTT9,
  552. g_F16, FLTS4, g_F17, FLTS5, g_F18, FLTS6, g_F19, FLTS7,
  553. g_F20, FLTS8, g_F21, FLTS9, g_F22, FLTS10, g_F23, FLTS11,
  554. g_F24, FLTS12, g_F25, FLTS13, g_F26, FLTS14, g_F27, FLTS15,
  555. g_F28, FLTS16, g_F29, FLTS17, g_F30, FLTS18, g_F31, FLTS19,
  556. szF32, FLTF32, szF33, FLTF33, szF34, FLTF34, szF35, FLTF35,
  557. szF36, FLTF36, szF37, FLTF37, szF38, FLTF38, szF39, FLTF39,
  558. szF40, FLTF40, szF41, FLTF41, szF42, FLTF42, szF43, FLTF43,
  559. szF44, FLTF44, szF45, FLTF45, szF46, FLTF46, szF47, FLTF47,
  560. szF48, FLTF48, szF49, FLTF49, szF50, FLTF50, szF51, FLTF51,
  561. szF52, FLTF52, szF53, FLTF53, szF54, FLTF54, szF55, FLTF55,
  562. szF56, FLTF56, szF57, FLTF57, szF58, FLTF58, szF59, FLTF59,
  563. szF60, FLTF60, szF61, FLTF61, szF62, FLTF62, szF63, FLTF63,
  564. szF64, FLTF64, szF65, FLTF65, szF66, FLTF66, szF67, FLTF67,
  565. szF68, FLTF68, szF69, FLTF69, szF70, FLTF70, szF71, FLTF71,
  566. szF72, FLTF72, szF73, FLTF73, szF74, FLTF74, szF75, FLTF75,
  567. szF76, FLTF76, szF77, FLTF77, szF78, FLTF78, szF79, FLTF79,
  568. szF80, FLTF80, szF81, FLTF81, szF82, FLTF82, szF83, FLTF83,
  569. szF84, FLTF84, szF85, FLTF85, szF86, FLTF86, szF87, FLTF87,
  570. szF88, FLTF88, szF89, FLTF89, szF90, FLTF90, szF91, FLTF91,
  571. szF92, FLTF92, szF93, FLTF93, szF94, FLTF94, szF95, FLTF95,
  572. szF96, FLTF96, szF97, FLTF97, szF98, FLTF98, szF99, FLTF99,
  573. szF100, FLTF100, szF101, FLTF101, szF102, FLTF102, szF103, FLTF103,
  574. szF104, FLTF104, szF105, FLTF105, szF106, FLTF106, szF107, FLTF107,
  575. szF108, FLTF108, szF109, FLTF109, szF110, FLTF110, szF111, FLTF111,
  576. szF112, FLTF112, szF113, FLTF113, szF114, FLTF114, szF115, FLTF115,
  577. szF116, FLTF116, szF117, FLTF117, szF118, FLTF118, szF119, FLTF119,
  578. szF120, FLTF120, szF121, FLTF121, szF122, FLTF122, szF123, FLTF123,
  579. szF124, FLTF124, szF125, FLTF125, szF126, FLTF126, szF127, FLTF127,
  580. szFPSR, STFPSR,
  581. // g_R0, INTZERO,
  582. szGP, INTGP, g_R2, INTT0, g_R3, INTT1,
  583. g_R4, INTS0, g_R5, INTS1, g_R6, INTS2, g_R7, INTS3,
  584. g_R8, INTV0, g_R9, INTT2, g_R10, INTT3, g_R11, INTT4,
  585. szSP, INTSP, g_R13, INTTEB, g_R14, INTT5, g_R15, INTT6,
  586. g_R16, INTT7, g_R17, INTT8, g_R18, INTT9, g_R19, INTT10,
  587. g_R20, INTT11, g_R21, INTT12, g_R22, INTT13, g_R23, INTT14,
  588. g_R24, INTT15, g_R25, INTT16, g_R26, INTT17, g_R27, INTT18,
  589. g_R28, INTT19, g_R29, INTT20, g_R30, INTT21, g_R31, INTT22,
  590. szINTNATS, INTNATS,
  591. szR32, INTR32, szR33, INTR33, szR34, INTR34, szR35, INTR35,
  592. szR36, INTR36, szR37, INTR37, szR38, INTR38, szR39, INTR39,
  593. szR40, INTR40, szR41, INTR41, szR42, INTR42, szR42, INTR42,
  594. szR43, INTR43, szR44, INTR44, szR45, INTR45, szR46, INTR46,
  595. szR47, INTR47, szR48, INTR48, szR49, INTR49, szR50, INTR50,
  596. szR51, INTR51, szR52, INTR52, szR53, INTR53, szR54, INTR54,
  597. szR55, INTR55, szR56, INTR56, szR57, INTR57, szR58, INTR58,
  598. szR59, INTR59, szR60, INTR60, szR61, INTR61, szR62, INTR62,
  599. szR63, INTR63, szR64, INTR64, szR65, INTR65, szR66, INTR66,
  600. szR67, INTR67, szR68, INTR68, szR69, INTR69, szR70, INTR70,
  601. szR71, INTR71, szR72, INTR72, szR73, INTR73, szR74, INTR74,
  602. szR75, INTR75, szR76, INTR76, szR77, INTR77, szR78, INTR78,
  603. szR79, INTR79, szR80, INTR80, szR81, INTR81, szR82, INTR82,
  604. szR83, INTR83, szR84, INTR84, szR85, INTR85, szR86, INTR86,
  605. szR87, INTR87, szR88, INTR88, szR89, INTR89, szR90, INTR90,
  606. szR91, INTR91, szR92, INTR92, szR93, INTR93, szR94, INTR94,
  607. szR95, INTR95, szR96, INTR96, szR97, INTR97, szR98, INTR98,
  608. szR99, INTR99, szR100, INTR100, szR101, INTR101, szR102, INTR102,
  609. szR103, INTR103, szR104, INTR104, szR105, INTR105, szR106, INTR106,
  610. szR107, INTR107, szR108, INTR108, szR109, INTR109, szR110, INTR110,
  611. szR111, INTR111, szR112, INTR112, szR112, INTR113, szR114, INTR114,
  612. szR115, INTR115, szR116, INTR116, szR117, INTR117, szR118, INTR118,
  613. szR119, INTR119, szR120, INTR120, szR121, INTR121, szR122, INTR122,
  614. szR123, INTR123, szR124, INTR124, szR125, INTR125, szR126, INTR126,
  615. szR127, INTR127,
  616. szPREDS, PREDS,
  617. szB0, BRRP, szB1, BRS0, szB2, BRS1, szB3, BRS2,
  618. szB4, BRS3, szB5, BRS4, szB6, BRT0, szB7, BRT1,
  619. szAPUNAT, APUNAT, szAPLC, APLC,
  620. szAPEC, APEC, szAPCCV, APCCV, szAPDCR, APDCR, szRSPFS, RSPFS,
  621. szRSBSP, RSBSP, szRSBSPSTORE, RSBSPSTORE, szRSRSC, RSRSC, szRSRNAT, RSRNAT,
  622. szSTIPSR, STIPSR, szSTIIP, STIIP, szSTIFS, STIFS,
  623. szFCR, StFCR,
  624. szEFLAG, Eflag,
  625. szCSD, SegCSD,
  626. szSSD, SegSSD,
  627. szCFLAG, Cflag,
  628. szFSR, STFSR,
  629. szFIR, STFIR,
  630. szFDR, STFDR,
  631. // IPSR flags
  632. szIPSRBN, IPSRBN,
  633. szIPSRED, IPSRED, szIPSRRI, IPSRRI, szIPSRSS, IPSRSS, szIPSRDD, IPSRDD,
  634. szIPSRDA, IPSRDA, szIPSRID, IPSRID, szIPSRIT, IPSRIT, szIPSRME, IPSRME,
  635. szIPSRIS, IPSRIS, szIPSRCPL, IPSRCPL, szIPSRRT, IPSRRT, szIPSRTB, IPSRTB,
  636. szIPSRLP, IPSRLP, szIPSRDB, IPSRDB, szIPSRSI, IPSRSI, szIPSRDI, IPSRDI,
  637. szIPSRPP, IPSRPP, szIPSRSP, IPSRSP, szIPSRDFH, IPSRDFH, szIPSRDFL, IPSRDFL,
  638. szIPSRDT, IPSRDT, szIPSRPK, IPSRPK, szIPSRI, IPSRI, szIPSRIC, IPSRIC,
  639. szIPSRAC, IPSRAC, szIPSRUP, IPSRUP, szIPSRBE, IPSRBE, szIPSROR, IPSROR,
  640. // FPSR flags
  641. szFPSRMDH, FPSRMDH, szFPSRMDL, FPSRMDL,
  642. szFPSRSF3, FPSRSF3, szFPSRSF2, FPSRSF2,
  643. szFPSRSF1, FPSRSF1, szFPSRSF0, FPSRSF0,
  644. szFPSRTRAPID, FPSRTRAPID, szFPSRTRAPUD, FPSRTRAPUD,
  645. szFPSRTRAPOD, FPSRTRAPOD, szFPSRTRAPZD, FPSRTRAPZD,
  646. szFPSRTRAPDD, FPSRTRAPDD, szFPSRTRAPVD, FPSRTRAPVD,
  647. // Predicate registers
  648. // szPR0, PR0,
  649. szPR1, PR1, szPR2, PR2, szPR3, PR3,
  650. szPR4, PR4, szPR5, PR5, szPR6, PR6, szPR7, PR7,
  651. szPR8, PR8, szPR9, PR9, szPR10, PR10, szPR11, PR11,
  652. szPR12, PR12, szPR13, PR13, szPR14, PR14, szPR15, PR15,
  653. szPR16, PR16, szPR17, PR17, szPR18, PR18, szPR19, PR19,
  654. szPR20, PR20, szPR21, PR21, szPR22, PR22, szPR23, PR23,
  655. szPR24, PR24, szPR25, PR25, szPR26, PR26, szPR27, PR27,
  656. szPR28, PR28, szPR29, PR29, szPR30, PR30, szPR31, PR31,
  657. szPR32, PR32, szPR33, PR33, szPR34, PR34, szPR35, PR35,
  658. szPR36, PR36, szPR37, PR37, szPR38, PR38, szPR39, PR39,
  659. szPR40, PR40, szPR41, PR41, szPR42, PR42, szPR43, PR43,
  660. szPR44, PR44, szPR45, PR45, szPR46, PR46, szPR47, PR47,
  661. szPR48, PR48, szPR49, PR49, szPR50, PR50, szPR51, PR51,
  662. szPR52, PR52, szPR53, PR53, szPR54, PR54, szPR55, PR55,
  663. szPR56, PR56, szPR57, PR57, szPR58, PR58, szPR59, PR59,
  664. szPR60, PR60, szPR61, PR61, szPR62, PR62, szPR63, PR63,
  665. // Aliases
  666. szR1GP, INTGP, szR12SP, INTSP, szRA, BRRP, szRP, BRRP,
  667. szRET0, INTV0, szRET1, INTT2, szRET2, INTT3, szRET3, INTT4,
  668. NULL, 0,
  669. };
  670. REGDEF g_Ia64KernelRegs[] =
  671. {
  672. szKDBI0, KRDBI0, szKDBI1, KRDBI1, szKDBI2, KRDBI2, szKDBI3, KRDBI3,
  673. szKDBI4, KRDBI4, szKDBI5, KRDBI5, szKDBI6, KRDBI6, szKDBI7, KRDBI7,
  674. szKDBD0, KRDBD0, szKDBD1, KRDBD1, szKDBD2, KRDBD2, szKDBD3, KRDBD3,
  675. szKDBD4, KRDBD4, szKDBD5, KRDBD5, szKDBD6, KRDBD6, szKDBD7, KRDBD7,
  676. szKPFC0, KRPFC0, szKPFC1, KRPFC1, szKPFC2, KRPFC2, szKPFC3, KRPFC3,
  677. szKPFC4, KRPFC4, szKPFC5, KRPFC5, szKPFC6, KRPFC6, szKPFC7, KRPFC7,
  678. szKPFD0, KRPFD0, szKPFD1, KRPFD1, szKPFD2, KRPFD2, szKPFD3, KRPFD3,
  679. szKPFD4, KRPFD4, szKPFD5, KRPFD5, szKPFD6, KRPFD6, szKPFD7, KRPFD7,
  680. szH16, INTH16, szH17, INTH17, szH18, INTH18, szH19, INTH19,
  681. szH20, INTH20, szH21, INTH21, szH22, INTH22, szH23, INTH23,
  682. szH24, INTH24, szH25, INTH25, szH26, INTH26, szH27, INTH27,
  683. szH28, INTH28, szH29, INTH29, szH30, INTH30, szH31, INTH31,
  684. szACPUID0, ACPUID0, szACPUID1, ACPUID1, szACPUID2, ACPUID2, szACPUID3, ACPUID3,
  685. szACPUID4, ACPUID4, szACPUID5, ACPUID5, szACPUID6, ACPUID6, szACPUID7, ACPUID7,
  686. szAPKR0, APKR0, szAPKR1, APKR1, szAPKR2, APKR2, szAPKR3, APKR3,
  687. szAPKR4, APKR4, szAPKR5, APKR5, szAPKR6, APKR6, szAPKR7, APKR7,
  688. szAPITC, APITC, szAPITM, APITM, szAPIVA, APIVA,
  689. szAPPTA, APPTA, szAPGPTA, APGPTA,
  690. szSTISR, STISR, szSTIDA, STIDA,
  691. szSTIITR, STIITR, szSTIIPA, STIIPA, szSTIIM, STIIM, szSTIHA, STIHA,
  692. szSALID, SALID,
  693. szSAIVR, SAIVR, szSATPR, SATPR, szSAEOI, SAEOI, szSAIRR0, SAIRR0,
  694. szSAIRR1, SAIRR1, szSAIRR2, SAIRR2, szSAIRR3, SAIRR3, szSAITV, SAITV,
  695. szSAPMV, SAPMV, szSACMCV, SACMCV, szSALRR0, SALRR0, szSALRR1, SALRR1,
  696. szRR0, SRRR0, szRR1, SRRR1, szRR2, SRRR2, szRR3, SRRR3,
  697. szRR4, SRRR4, szRR5, SRRR5, szRR6, SRRR6, szRR7, SRRR7,
  698. szPKR0, SRPKR0, szPKR1, SRPKR1, szPKR2, SRPKR2, szPKR3, SRPKR3,
  699. szPKR4, SRPKR4, szPKR5, SRPKR5, szPKR6, SRPKR6, szPKR7, SRPKR7,
  700. szPKR8, SRPKR8, szPKR9, SRPKR9, szPKR10, SRPKR10, szPKR11, SRPKR11,
  701. szPKR12, SRPKR12, szPKR13, SRPKR13, szPKR14, SRPKR14, szPKR15, SRPKR15,
  702. szTRI0, SRTRI0, szTRI1, SRTRI1, szTRI2, SRTRI2, szTRI3, SRTRI3,
  703. szTRI4, SRTRI4, szTRI5, SRTRI5, szTRI6, SRTRI6, szTRI7, SRTRI7,
  704. szTRD0, SRTRD0, szTRD1, SRTRD1, szTRD2, SRTRD2, szTRD3, SRTRD3,
  705. szTRD4, SRTRD4, szTRD5, SRTRD5, szTRD6, SRTRD6, szTRD7, SRTRD7,
  706. szSMSR0, SMSR0, szSMSR1, SMSR1, szSMSR2, SMSR2, szSMSR3, SMSR3,
  707. szSMSR4, SMSR4, szSMSR5, SMSR5, szSMSR6, SMSR6, szSMSR7, SMSR7,
  708. NULL, 0,
  709. };
  710. REGSUBDEF IA64SubRegs[] =
  711. {
  712. // IPSR flags
  713. { IPSRBN, STIPSR, 44, 1 }, // BN Register bank #
  714. { IPSRED, STIPSR, 43, 1 }, // ED Exception deferal
  715. { IPSRRI, STIPSR, 41, 0x3 }, // RI Restart instruction
  716. { IPSRSS, STIPSR, 40, 1 }, // SS Single step enable
  717. { IPSRDD, STIPSR, 39, 1 }, // DD Data debug fault disable
  718. { IPSRDA, STIPSR, 38, 1 }, // DA Disable access and dirty-bit faults
  719. { IPSRID, STIPSR, 37, 1 }, // ID Instruction debug fault disable
  720. { IPSRIT, STIPSR, 36, 1 }, // IT Instruction address translation
  721. { IPSRME, STIPSR, 35, 1 }, // ME Machine check abort mamsk
  722. { IPSRIS, STIPSR, 34, 1 }, // IS Instruction set
  723. { IPSRCPL,STIPSR, 32, 0x3 }, // CPL Current privilege level
  724. { IPSRRT, STIPSR, 27, 1 }, // RT Rigister stack translation
  725. { IPSRTB, STIPSR, 26, 1 }, // TB Taaaaken branch trap
  726. { IPSRLP, STIPSR, 25, 1 }, // LP Lower privilege transfer trap
  727. { IPSRDB, STIPSR, 24, 1 }, // DB Debug breakpoint fault
  728. { IPSRSI, STIPSR, 23, 1 }, // SI Secure interval timer(ITC)
  729. { IPSRDI, STIPSR, 22, 1 }, // DI Disable instruction set transition
  730. { IPSRPP, STIPSR, 21, 1 }, // PP Privileged performance monitor enable
  731. { IPSRSP, STIPSR, 20, 1 }, // SP Secure performance monitors
  732. { IPSRDFH,STIPSR, 19, 1 }, // DFH Disabled floating-point high register set, f16-f127
  733. { IPSRDFL,STIPSR, 18, 1 }, // DFL Disabled floating-point low register set, f0-f15
  734. { IPSRDT, STIPSR, 17, 1 }, // DT Data address translation
  735. // { ?, STIPSR, 16, 1 }, // (reserved)
  736. { IPSRPK, STIPSR, 15, 1 }, // PK Protection key enabled
  737. { IPSRI, STIPSR, 14, 1 }, // I Interrupt unmask
  738. { IPSRIC, STIPSR, 13, 1 }, // IC Interruption collection
  739. { IPSRAC, STIPSR, 3, 1 }, // AC Alignment check
  740. { IPSRUP, STIPSR, 2, 1 }, // UP User performance monitor enabled
  741. { IPSRBE, STIPSR, 1, 1 }, // BE Big-Endian
  742. { IPSROR, STIPSR, 0, 1 }, // OR Ordered memory reference
  743. // FPSR flags
  744. { FPSRMDH, STFPSR, 63, 1 }, // MDH Upper floating point register written
  745. { FPSRMDL, STFPSR, 62, 1 }, // MDL Lower floating point register written
  746. { FPSRSF3, STFPSR, 45, 0x1fff }, // SF3 Alternate status field 3
  747. { FPSRSF2, STFPSR, 32, 0x1fff }, // SF2 Alternate status field 2
  748. { FPSRSF1, STFPSR, 19, 0x1fff }, // SF1 Alternate status field 1
  749. { FPSRSF0, STFPSR, 6, 0x1fff }, // SF0 Main status field
  750. { FPSRTRAPID, STFPSR, 5, 1 }, // TRAPID Inexact floating point trap
  751. { FPSRTRAPUD, STFPSR, 4, 1 }, // TRAPUD Underflow floating point trap
  752. { FPSRTRAPOD, STFPSR, 3, 1 }, // TRAPOD Overflow flating point trap
  753. { FPSRTRAPZD, STFPSR, 2, 1 }, // TRAPZD Zero devide floating point trap
  754. { FPSRTRAPDD, STFPSR, 1, 1 }, // TRAPDD Denormal/Unnormal operand floating point trap
  755. { FPSRTRAPVD, STFPSR, 0, 1 }, // TRAPVD Invalid operation floating point trap
  756. // Predicate registers
  757. // { PR0, PREDS, 0, 1 },
  758. { PR1, PREDS, 1, 1 },
  759. { PR2, PREDS, 2, 1 },
  760. { PR3, PREDS, 3, 1 },
  761. { PR4, PREDS, 4, 1 },
  762. { PR5, PREDS, 5, 1 },
  763. { PR6, PREDS, 6, 1 },
  764. { PR7, PREDS, 7, 1 },
  765. { PR8, PREDS, 8, 1 },
  766. { PR9, PREDS, 9, 1 },
  767. { PR10, PREDS, 10, 1 },
  768. { PR11, PREDS, 11, 1 },
  769. { PR12, PREDS, 12, 1 },
  770. { PR13, PREDS, 13, 1 },
  771. { PR14, PREDS, 14, 1 },
  772. { PR15, PREDS, 15, 1 },
  773. { PR16, PREDS, 16, 1 },
  774. { PR17, PREDS, 17, 1 },
  775. { PR18, PREDS, 18, 1 },
  776. { PR19, PREDS, 19, 1 },
  777. { PR20, PREDS, 20, 1 },
  778. { PR21, PREDS, 21, 1 },
  779. { PR22, PREDS, 22, 1 },
  780. { PR23, PREDS, 23, 1 },
  781. { PR24, PREDS, 24, 1 },
  782. { PR25, PREDS, 25, 1 },
  783. { PR26, PREDS, 26, 1 },
  784. { PR27, PREDS, 27, 1 },
  785. { PR28, PREDS, 28, 1 },
  786. { PR29, PREDS, 29, 1 },
  787. { PR30, PREDS, 30, 1 },
  788. { PR31, PREDS, 31, 1 },
  789. { PR32, PREDS, 32, 1 },
  790. { PR33, PREDS, 33, 1 },
  791. { PR34, PREDS, 34, 1 },
  792. { PR35, PREDS, 35, 1 },
  793. { PR36, PREDS, 36, 1 },
  794. { PR37, PREDS, 37, 1 },
  795. { PR38, PREDS, 38, 1 },
  796. { PR39, PREDS, 39, 1 },
  797. { PR40, PREDS, 40, 1 },
  798. { PR41, PREDS, 41, 1 },
  799. { PR42, PREDS, 42, 1 },
  800. { PR43, PREDS, 43, 1 },
  801. { PR44, PREDS, 44, 1 },
  802. { PR45, PREDS, 45, 1 },
  803. { PR46, PREDS, 46, 1 },
  804. { PR47, PREDS, 47, 1 },
  805. { PR48, PREDS, 48, 1 },
  806. { PR49, PREDS, 49, 1 },
  807. { PR50, PREDS, 50, 1 },
  808. { PR51, PREDS, 51, 1 },
  809. { PR52, PREDS, 52, 1 },
  810. { PR53, PREDS, 53, 1 },
  811. { PR54, PREDS, 54, 1 },
  812. { PR55, PREDS, 55, 1 },
  813. { PR56, PREDS, 56, 1 },
  814. { PR57, PREDS, 57, 1 },
  815. { PR58, PREDS, 58, 1 },
  816. { PR59, PREDS, 59, 1 },
  817. { PR60, PREDS, 60, 1 },
  818. { PR61, PREDS, 61, 1 },
  819. { PR62, PREDS, 62, 1 },
  820. { PR63, PREDS, 63, 1 },
  821. { 0, 0, 0 }
  822. };
  823. #define REGALL_HIGHFLOAT REGALL_EXTRA0
  824. #define REGALL_DREG REGALL_EXTRA1
  825. REGALLDESC IA64ExtraDesc[] =
  826. {
  827. REGALL_HIGHFLOAT, "High floating pointer registers (f32-f127)",
  828. REGALL_DREG, "User debug registers",
  829. 0, NULL,
  830. };
  831. #define REGALL_SPECIALREG REGALL_EXTRA2
  832. REGALLDESC g_Ia64KernelExtraDesc[] =
  833. {
  834. REGALL_SPECIALREG, "KSPECIAL_REGISTERS",
  835. 0, NULL,
  836. };
  837. RegisterGroup g_Ia64BaseGroup =
  838. {
  839. NULL, 0, IA64Regs, IA64SubRegs, IA64ExtraDesc
  840. };
  841. RegisterGroup g_Ia64KernelGroup =
  842. {
  843. NULL, 0, g_Ia64KernelRegs, NULL, g_Ia64KernelExtraDesc
  844. };
  845. // First ExecTypes entry must be the actual processor type.
  846. ULONG g_Ia64ExecTypes[] =
  847. {
  848. IMAGE_FILE_MACHINE_IA64, IMAGE_FILE_MACHINE_I386
  849. };
  850. BOOL
  851. SplitIa64Pc(ULONG64 Pc, ULONG64* Bundle, ULONG64* Slot)
  852. {
  853. ULONG64 SlotVal = Pc & 0xf;
  854. switch (SlotVal)
  855. {
  856. case 0:
  857. case 4:
  858. case 8:
  859. SlotVal >>= 2;
  860. break;
  861. default:
  862. return FALSE;
  863. }
  864. if (Slot)
  865. {
  866. *Slot = SlotVal;
  867. }
  868. if (Bundle)
  869. {
  870. *Bundle = Pc & ~(ULONG64)0xf;
  871. }
  872. return TRUE;
  873. }
  874. Ia64MachineInfo g_Ia64Machine;
  875. HRESULT
  876. Ia64MachineInfo::InitializeConstants(void)
  877. {
  878. m_FullName = "Intel IA64";
  879. m_AbbrevName = "ia64";
  880. m_PageSize = IA64_PAGE_SIZE;
  881. m_PageShift = IA64_PAGE_SHIFT;
  882. m_NumExecTypes = 2;
  883. m_ExecTypes = g_Ia64ExecTypes;
  884. m_Ptr64 = TRUE;
  885. m_AllMask = REGALL_INT64 | REGALL_DREG,
  886. m_MaxDataBreakpoints = IA64_REG_MAX_DATA_BREAKPOINTS;
  887. m_SymPrefix = NULL;
  888. m_KernPageDir = 0;
  889. return MachineInfo::InitializeConstants();
  890. }
  891. HRESULT
  892. Ia64MachineInfo::InitializeForTarget(void)
  893. {
  894. m_Groups = &g_Ia64BaseGroup;
  895. g_Ia64BaseGroup.Next = NULL;
  896. if (IS_KERNEL_TARGET())
  897. {
  898. g_Ia64BaseGroup.Next = &g_Ia64KernelGroup;
  899. }
  900. m_OffsetPrcbProcessorState =
  901. FIELD_OFFSET(IA64_PARTIAL_KPRCB, ProcessorState);
  902. m_OffsetPrcbNumber =
  903. FIELD_OFFSET(IA64_PARTIAL_KPRCB, Number);
  904. m_TriagePrcbOffset = IA64_TRIAGE_PRCB_ADDRESS;
  905. m_SizePrcb = IA64_KPRCB_SIZE;
  906. m_OffsetKThreadApcProcess =
  907. FIELD_OFFSET(CROSS_PLATFORM_THREAD, IA64Thread.ApcState.Process);
  908. m_OffsetKThreadTeb =
  909. FIELD_OFFSET(CROSS_PLATFORM_THREAD, IA64Thread.Teb);
  910. m_OffsetKThreadInitialStack =
  911. FIELD_OFFSET(CROSS_PLATFORM_THREAD, IA64Thread.InitialStack);
  912. m_OffsetKThreadNextProcessor = IA64_KTHREAD_NEXTPROCESSOR_OFFSET;
  913. m_OffsetEprocessPeb = (g_TargetBuildNumber < 2264 ) ?
  914. IA64_PEB_IN_EPROCESS : IA64_2259_PEB_IN_EPROCESS;
  915. m_OffsetEprocessDirectoryTableBase =
  916. IA64_DIRECTORY_TABLE_BASE_IN_EPROCESS;
  917. m_SizeTargetContext = sizeof(IA64_CONTEXT);
  918. m_OffsetTargetContextFlags = FIELD_OFFSET(IA64_CONTEXT, ContextFlags);
  919. m_SizeCanonicalContext = sizeof(IA64_CONTEXT);
  920. m_SverCanonicalContext = NT_SVER_W2K;
  921. m_SizeControlReport = sizeof(IA64_DBGKD_CONTROL_REPORT);
  922. m_SizeEThread = IA64_ETHREAD_SIZE;
  923. m_SizeEProcess = IA64_EPROCESS_SIZE;
  924. m_OffsetSpecialRegisters = IA64_DEBUG_CONTROL_SPACE_KSPECIAL;
  925. m_SizeKspecialRegisters = sizeof(IA64_KSPECIAL_REGISTERS);
  926. m_SizePartialKThread = sizeof(IA64_THREAD);
  927. m_SharedUserDataOffset = IS_KERNEL_TARGET() ?
  928. IA64_KI_USER_SHARED_DATA : MM_SHARED_USER_DATA_VA;
  929. return MachineInfo::InitializeForTarget();
  930. }
  931. void
  932. Ia64MachineInfo::
  933. InitializeContext(ULONG64 Pc,
  934. PDBGKD_ANY_CONTROL_REPORT ControlReport)
  935. {
  936. if (Pc)
  937. {
  938. ULONG Slot;
  939. m_ContextState = MCTX_PC;
  940. Slot = (ULONG)(Pc & 0xc) >> 2;
  941. m_Context.IA64Context.StIIP = Pc & ~(0xf);
  942. m_Context.IA64Context.StIPSR &= ~(IPSR_RI_MASK);
  943. m_Context.IA64Context.StIPSR |= (ULONGLONG)Slot << PSR_RI;
  944. }
  945. else
  946. {
  947. m_Context.IA64Context.StIIP = Pc;
  948. }
  949. if (Pc && ControlReport != NULL)
  950. {
  951. CacheReportInstructions
  952. (Pc, ControlReport->IA64ControlReport.InstructionCount,
  953. ControlReport->IA64ControlReport.InstructionStream);
  954. }
  955. }
  956. HRESULT
  957. Ia64MachineInfo::KdGetContextState(ULONG State)
  958. {
  959. HRESULT Status;
  960. if (State >= MCTX_CONTEXT && m_ContextState < MCTX_CONTEXT)
  961. {
  962. Status = g_Target->GetContext(g_RegContextThread->Handle, &m_Context);
  963. if (Status != S_OK)
  964. {
  965. return Status;
  966. }
  967. m_ContextState = MCTX_CONTEXT;
  968. }
  969. if (State >= MCTX_FULL && m_ContextState < MCTX_FULL)
  970. {
  971. Status = g_Target->GetTargetSpecialRegisters
  972. (g_RegContextThread->Handle, (PCROSS_PLATFORM_KSPECIAL_REGISTERS)
  973. &m_SpecialRegContext);
  974. if (Status != S_OK)
  975. {
  976. return Status;
  977. }
  978. m_ContextState = MCTX_FULL;
  979. KdSetSpecialRegistersInContext();
  980. }
  981. return S_OK;
  982. }
  983. HRESULT
  984. Ia64MachineInfo::KdSetContext(void)
  985. {
  986. HRESULT Status;
  987. Status = g_Target->SetContext(g_RegContextThread->Handle, &m_Context);
  988. if (Status != S_OK)
  989. {
  990. return Status;
  991. }
  992. KdGetSpecialRegistersFromContext();
  993. Status = g_Target->SetTargetSpecialRegisters
  994. (g_RegContextThread->Handle, (PCROSS_PLATFORM_KSPECIAL_REGISTERS)
  995. &m_SpecialRegContext);
  996. if (Status != S_OK)
  997. {
  998. return Status;
  999. }
  1000. return S_OK;
  1001. }
  1002. HRESULT
  1003. Ia64MachineInfo::ConvertContextFrom(PCROSS_PLATFORM_CONTEXT Context,
  1004. ULONG FromSver, ULONG FromSize, PVOID From)
  1005. {
  1006. if (FromSize < sizeof(IA64_CONTEXT))
  1007. {
  1008. return E_INVALIDARG;
  1009. }
  1010. memcpy(Context, From, sizeof(IA64_CONTEXT));
  1011. return S_OK;
  1012. }
  1013. HRESULT
  1014. Ia64MachineInfo::ConvertContextTo(PCROSS_PLATFORM_CONTEXT Context,
  1015. ULONG ToSver, ULONG ToSize, PVOID To)
  1016. {
  1017. if (ToSize < sizeof(IA64_CONTEXT))
  1018. {
  1019. return E_INVALIDARG;
  1020. }
  1021. memcpy(To, Context, sizeof(IA64_CONTEXT));
  1022. return S_OK;
  1023. }
  1024. void
  1025. Ia64MachineInfo::InitializeContextFlags(PCROSS_PLATFORM_CONTEXT Context,
  1026. ULONG Version)
  1027. {
  1028. Context->IA64Context.ContextFlags =
  1029. IA64_CONTEXT_FULL | IA64_CONTEXT_DEBUG;
  1030. }
  1031. HRESULT
  1032. Ia64MachineInfo::GetContextFromThreadStack(ULONG64 ThreadBase,
  1033. PCROSS_PLATFORM_THREAD Thread,
  1034. PCROSS_PLATFORM_CONTEXT Context,
  1035. PDEBUG_STACK_FRAME Frame,
  1036. PULONG RunningOnProc)
  1037. {
  1038. HRESULT Status;
  1039. UCHAR Proc;
  1040. //
  1041. // Check to see if the thread is currently running.
  1042. //
  1043. if (Thread->IA64Thread.State == 2)
  1044. {
  1045. if ((Status = g_Target->ReadAllVirtual
  1046. (ThreadBase + m_OffsetKThreadNextProcessor,
  1047. &Proc, sizeof(Proc))) != S_OK)
  1048. {
  1049. return Status;
  1050. }
  1051. *RunningOnProc = Proc;
  1052. return S_FALSE;
  1053. }
  1054. //
  1055. // The thread isn't running so read its stored context information.
  1056. //
  1057. IA64_KSWITCH_FRAME SwitchFrame;
  1058. if ((Status = g_Target->ReadAllVirtual(Thread->IA64Thread.KernelStack +
  1059. IA64_STACK_SCRATCH_AREA,
  1060. &SwitchFrame,
  1061. sizeof(SwitchFrame))) != S_OK)
  1062. {
  1063. return Status;
  1064. }
  1065. Context->IA64Context.IntSp =
  1066. Thread->IA64Thread.KernelStack;
  1067. Context->IA64Context.Preds = SwitchFrame.SwitchPredicates;
  1068. Context->IA64Context.StIIP = SwitchFrame.SwitchRp;
  1069. Context->IA64Context.StFPSR = SwitchFrame.SwitchFPSR;
  1070. Context->IA64Context.BrRp = SwitchFrame.SwitchRp;
  1071. Context->IA64Context.RsPFS = SwitchFrame.SwitchPFS;
  1072. Context->IA64Context.StIFS = SwitchFrame.SwitchPFS;
  1073. SHORT BsFrameSize =
  1074. (SHORT)(SwitchFrame.SwitchPFS >> IA64_PFS_SIZE_SHIFT) &
  1075. IA64_PFS_SIZE_MASK;
  1076. SHORT TempFrameSize =
  1077. BsFrameSize - (SHORT)((SwitchFrame.SwitchBsp >> 3) &
  1078. IA64_NAT_BITS_PER_RNAT_REG);
  1079. while (TempFrameSize > 0)
  1080. {
  1081. BsFrameSize++;
  1082. TempFrameSize -= IA64_NAT_BITS_PER_RNAT_REG;
  1083. }
  1084. Context->IA64Context.RsBSP =
  1085. SwitchFrame.SwitchBsp - (BsFrameSize * sizeof(ULONGLONG));
  1086. Context->IA64Context.FltS0 = SwitchFrame.SwitchExceptionFrame.FltS0;
  1087. Context->IA64Context.FltS1 = SwitchFrame.SwitchExceptionFrame.FltS1;
  1088. Context->IA64Context.FltS2 = SwitchFrame.SwitchExceptionFrame.FltS2;
  1089. Context->IA64Context.FltS3 = SwitchFrame.SwitchExceptionFrame.FltS3;
  1090. Context->IA64Context.FltS4 = SwitchFrame.SwitchExceptionFrame.FltS4;
  1091. Context->IA64Context.FltS5 = SwitchFrame.SwitchExceptionFrame.FltS5;
  1092. Context->IA64Context.FltS6 = SwitchFrame.SwitchExceptionFrame.FltS6;
  1093. Context->IA64Context.FltS7 = SwitchFrame.SwitchExceptionFrame.FltS7;
  1094. Context->IA64Context.FltS8 = SwitchFrame.SwitchExceptionFrame.FltS8;
  1095. Context->IA64Context.FltS9 = SwitchFrame.SwitchExceptionFrame.FltS9;
  1096. Context->IA64Context.FltS10 = SwitchFrame.SwitchExceptionFrame.FltS10;
  1097. Context->IA64Context.FltS11 = SwitchFrame.SwitchExceptionFrame.FltS11;
  1098. Context->IA64Context.FltS12 = SwitchFrame.SwitchExceptionFrame.FltS12;
  1099. Context->IA64Context.FltS13 = SwitchFrame.SwitchExceptionFrame.FltS13;
  1100. Context->IA64Context.FltS14 = SwitchFrame.SwitchExceptionFrame.FltS14;
  1101. Context->IA64Context.FltS15 = SwitchFrame.SwitchExceptionFrame.FltS15;
  1102. Context->IA64Context.FltS16 = SwitchFrame.SwitchExceptionFrame.FltS16;
  1103. Context->IA64Context.FltS17 = SwitchFrame.SwitchExceptionFrame.FltS17;
  1104. Context->IA64Context.FltS18 = SwitchFrame.SwitchExceptionFrame.FltS18;
  1105. Context->IA64Context.FltS19 = SwitchFrame.SwitchExceptionFrame.FltS19;
  1106. Context->IA64Context.IntS0 = SwitchFrame.SwitchExceptionFrame.IntS0;
  1107. Context->IA64Context.IntS1 = SwitchFrame.SwitchExceptionFrame.IntS1;
  1108. Context->IA64Context.IntS2 = SwitchFrame.SwitchExceptionFrame.IntS2;
  1109. Context->IA64Context.IntS3 = SwitchFrame.SwitchExceptionFrame.IntS3;
  1110. Context->IA64Context.IntNats = SwitchFrame.SwitchExceptionFrame.IntNats;
  1111. Context->IA64Context.BrS0 = SwitchFrame.SwitchExceptionFrame.BrS0;
  1112. Context->IA64Context.BrS1 = SwitchFrame.SwitchExceptionFrame.BrS1;
  1113. Context->IA64Context.BrS2 = SwitchFrame.SwitchExceptionFrame.BrS2;
  1114. Context->IA64Context.BrS3 = SwitchFrame.SwitchExceptionFrame.BrS3;
  1115. Context->IA64Context.BrS4 = SwitchFrame.SwitchExceptionFrame.BrS4;
  1116. Context->IA64Context.ApEC = SwitchFrame.SwitchExceptionFrame.ApEC;
  1117. Context->IA64Context.ApLC = SwitchFrame.SwitchExceptionFrame.ApLC;
  1118. Frame->InstructionOffset = Context->IA64Context.StIIP;
  1119. Frame->StackOffset = Context->IA64Context.IntSp;
  1120. Frame->FrameOffset = Context->IA64Context.RsBSP;
  1121. return S_OK;
  1122. }
  1123. int
  1124. Ia64MachineInfo::GetType(ULONG index)
  1125. {
  1126. if (index >= IA64_FLTBASE && index <= IA64_FLTLAST)
  1127. {
  1128. return REGVAL_FLOAT82;
  1129. }
  1130. else if ((index >= INTGP && index <= INTT22) ||
  1131. (index >= INTR32 && index <= INTR127))
  1132. {
  1133. return REGVAL_INT64N;
  1134. }
  1135. else if (index < IA64_FLAGBASE)
  1136. {
  1137. return REGVAL_INT64;
  1138. }
  1139. else
  1140. {
  1141. return REGVAL_SUB64;
  1142. }
  1143. }
  1144. /*** RegGetVal - get register value
  1145. *
  1146. * Purpose:
  1147. * Returns the value of the register from the processor
  1148. * context structure.
  1149. *
  1150. * Input:
  1151. * regnum - register specification
  1152. *
  1153. * Returns:
  1154. * value of the register from the context structure
  1155. *
  1156. *************************************************************************/
  1157. BOOL
  1158. Ia64MachineInfo::GetVal (ULONG regnum, REGVAL *val)
  1159. {
  1160. switch(m_ContextState)
  1161. {
  1162. case MCTX_PC:
  1163. switch (regnum)
  1164. {
  1165. case STIIP:
  1166. val->type = REGVAL_INT64;
  1167. val->i64 = m_Context.IA64Context.StIIP;
  1168. return TRUE;
  1169. }
  1170. goto MctxContext;
  1171. case MCTX_REPORT:
  1172. #if 0
  1173. // place holder for Debug/Segment registers manipulation via
  1174. // Control REPORT message
  1175. switch (regnum)
  1176. {
  1177. case KRDBI0:
  1178. val->type = REGVAL_INT64;
  1179. val->i64 = SpecialRegContext.KernelDbi0;
  1180. return TRUE;
  1181. }
  1182. #endif
  1183. //
  1184. // Requested register was not in MCTX_REPORT - go get the next
  1185. // context level.
  1186. //
  1187. case MCTX_NONE:
  1188. MctxContext:
  1189. if (GetContextState(MCTX_CONTEXT) != S_OK)
  1190. {
  1191. return FALSE;
  1192. }
  1193. // Fallthrough!
  1194. case MCTX_CONTEXT:
  1195. if (regnum >= IA64_FLTBASE && regnum <= IA64_FLTLAST)
  1196. {
  1197. val->type = REGVAL_FLOAT82;
  1198. val->f16Parts.high = 0;
  1199. memcpy(val->f82,
  1200. (PULONGLONG)&m_Context.IA64Context.DbI0 + regnum,
  1201. sizeof(val->f82));
  1202. return TRUE;
  1203. }
  1204. else if ((regnum >= INTGP) && (regnum <= INTT22))
  1205. {
  1206. val->type = REGVAL_INT64N;
  1207. val->Nat = (UCHAR)((m_Context.IA64Context.IntNats >> (regnum - INTGP + 1)) & 0x1);
  1208. val->i64 = *((PULONGLONG)&m_Context.IA64Context.IntGp + regnum - INTGP);
  1209. return TRUE;
  1210. }
  1211. else if ((regnum >= INTR32) && (regnum <= INTR127))
  1212. {
  1213. USHORT FrameSize;
  1214. val->type = REGVAL_INT64N;
  1215. regnum -= INTR32;
  1216. FrameSize = (USHORT)(m_Context.IA64Context.StIFS & 0x7F);
  1217. if (regnum >= FrameSize) {
  1218. #if 0
  1219. ErrOut("RegGetVal: out-of-frame register r%ld requested\n",
  1220. regnum+32);
  1221. return FALSE;
  1222. #else
  1223. val->i64 = 0;
  1224. val->Nat = TRUE;
  1225. return TRUE;
  1226. #endif
  1227. }
  1228. return GetStackedRegVal(m_Context.IA64Context.RsBSP, FrameSize,
  1229. m_Context.IA64Context.RsRNAT, regnum, val);
  1230. }
  1231. else if (regnum < IA64_SRBASE)
  1232. {
  1233. val->type = REGVAL_INT64;
  1234. val->i64 = *((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum);
  1235. return TRUE;
  1236. }
  1237. //
  1238. // The requested register is not in our current context, load up
  1239. // a complete context
  1240. //
  1241. if (GetContextState(MCTX_FULL) != S_OK)
  1242. {
  1243. return FALSE;
  1244. }
  1245. }
  1246. //
  1247. // We must have a complete context...
  1248. //
  1249. if (regnum >= IA64_FLTBASE && regnum <= IA64_FLTLAST)
  1250. {
  1251. val->type = REGVAL_FLOAT82;
  1252. val->f16Parts.high = 0;
  1253. memcpy(val->f82,
  1254. (PULONGLONG)&m_Context.IA64Context.DbI0 + regnum,
  1255. sizeof(val->f82));
  1256. return TRUE;
  1257. }
  1258. else if ((regnum >= INTGP) && (regnum <= INTT22))
  1259. {
  1260. val->type = REGVAL_INT64N;
  1261. val->Nat = (UCHAR)((*((PULONGLONG)&m_Context.IA64Context.DbI0 + INTNATS) >> (regnum - INTGP + 1)) & 0x1);
  1262. val->i64 = *((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum);
  1263. return TRUE;
  1264. }
  1265. else if ((regnum >= INTR32) && (regnum <= INTR127))
  1266. {
  1267. USHORT FrameSize;
  1268. val->type = REGVAL_INT64N;
  1269. regnum -= INTR32;
  1270. FrameSize = (USHORT)(m_Context.IA64Context.StIFS & 0x7F);
  1271. if (regnum >= FrameSize) {
  1272. #if 0
  1273. ErrOut("RegGetVal: out-of-frame register r%ld requested\n",
  1274. regnum+32);
  1275. return FALSE;
  1276. #else
  1277. val->i64 = 0;
  1278. val->Nat = TRUE;
  1279. return TRUE;
  1280. #endif
  1281. }
  1282. return GetStackedRegVal(m_Context.IA64Context.RsBSP, FrameSize,
  1283. m_Context.IA64Context.RsRNAT, regnum, val);
  1284. }
  1285. else if (regnum < IA64_SRBASE)
  1286. {
  1287. val->type = REGVAL_INT64;
  1288. val->i64 = *((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum);
  1289. return TRUE;
  1290. }
  1291. else if (IS_KERNEL_TARGET() && regnum <= IA64_SREND)
  1292. {
  1293. val->type = REGVAL_INT64;
  1294. val->i64 = *((PULONGLONG)&m_SpecialRegContext.KernelDbI0 +
  1295. (regnum - IA64_SRBASE));
  1296. return TRUE;
  1297. }
  1298. else
  1299. {
  1300. ErrOut("Ia64MachineInfo::GetVal: "
  1301. "unknown register %lx requested\n", regnum);
  1302. return FALSE;
  1303. }
  1304. }
  1305. /*** RegSetVal - set register value
  1306. *
  1307. * Purpose:
  1308. * Set the value of the register in the processor context
  1309. * structure.
  1310. *
  1311. * Input:
  1312. * regnum - register specification
  1313. * regvalue - new value to set the register
  1314. *
  1315. * Output:
  1316. * None.
  1317. *
  1318. *************************************************************************/
  1319. BOOL
  1320. Ia64MachineInfo::SetVal (ULONG regnum, REGVAL *val)
  1321. {
  1322. if (m_ContextIsReadOnly)
  1323. {
  1324. return FALSE;
  1325. }
  1326. BOOL Ia32InstructionSet = IsIA32InstructionSet();
  1327. // Optimize away some common cases where registers are
  1328. // set to their current value.
  1329. if ((regnum == STIIP) && (m_ContextState >= MCTX_PC))
  1330. {
  1331. if (val->type != REGVAL_INT64)
  1332. {
  1333. return FALSE;
  1334. }
  1335. ULONG64 Slot, Bundle;
  1336. if ((Ia32InstructionSet &&
  1337. (m_Context.IA64Context.StIIP == val->i64)) ||
  1338. ((SplitIa64Pc(val->i64, &Bundle, &Slot) &&
  1339. (Bundle == m_Context.IA64Context.StIIP) &&
  1340. (Slot == ((m_Context.IA64Context.StIPSR & IPSR_RI_MASK) >>
  1341. PSR_RI)))))
  1342. {
  1343. return TRUE;
  1344. }
  1345. }
  1346. if (GetContextState(MCTX_DIRTY) != S_OK)
  1347. {
  1348. return FALSE;
  1349. }
  1350. if (regnum == STIIP)
  1351. {
  1352. ULONG64 Bundle, Slot;
  1353. if ((val->type != REGVAL_INT64) ||
  1354. !(Ia32InstructionSet || SplitIa64Pc(val->i64, &Bundle, &Slot)))
  1355. {
  1356. return FALSE;
  1357. }
  1358. if (Ia32InstructionSet)
  1359. {
  1360. m_Context.IA64Context.StIIP = val->i64;
  1361. }
  1362. else
  1363. {
  1364. m_Context.IA64Context.StIIP = Bundle;
  1365. (m_Context.IA64Context.StIPSR &= ~(IPSR_RI_MASK)) |=
  1366. (ULONGLONG)Slot << PSR_RI;
  1367. }
  1368. }
  1369. else if (regnum >= IA64_FLTBASE && regnum <= IA64_FLTLAST)
  1370. {
  1371. memcpy((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum,
  1372. val->f82, sizeof(val->f82));
  1373. }
  1374. else if ((regnum >= INTGP) && (regnum <= INTT22))
  1375. {
  1376. ULONG64 Mask = (0x1i64 << (regnum - INTGP + 1));
  1377. if (val->Nat) {
  1378. m_Context.IA64Context.IntNats |= Mask;
  1379. } else {
  1380. m_Context.IA64Context.IntNats &= ~Mask;
  1381. *((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum) = val->i64;
  1382. }
  1383. }
  1384. else if ((regnum >= INTR32) && (regnum <= INTR127))
  1385. {
  1386. USHORT FrameSize;
  1387. regnum -= INTR32;
  1388. FrameSize = (USHORT)(m_Context.IA64Context.StIFS & 0x7F);
  1389. if (regnum >= FrameSize) {
  1390. ErrOut("RegSetVal: out-of-frame register r%ld requested\n",
  1391. regnum+32);
  1392. return FALSE;
  1393. }
  1394. if (!SetStackedRegVal(m_Context.IA64Context.RsBSP, FrameSize,
  1395. &m_Context.IA64Context.RsRNAT, regnum, val))
  1396. {
  1397. return FALSE;
  1398. }
  1399. }
  1400. else if (regnum < IA64_SRBASE)
  1401. {
  1402. *((PULONGLONG)&m_Context.IA64Context.DbI0 + regnum) = val->i64;
  1403. }
  1404. else if (IS_KERNEL_TARGET() && regnum <= IA64_SREND)
  1405. {
  1406. *((PULONGLONG)&m_SpecialRegContext.KernelDbI0 + (regnum - IA64_SRBASE)) =
  1407. val->i64;
  1408. }
  1409. else
  1410. {
  1411. ErrOut("Ia64MachineInfo::SetVal: "
  1412. "unknown register %lx requested\n", regnum);
  1413. return FALSE;
  1414. }
  1415. NotifyChangeDebuggeeState(DEBUG_CDS_REGISTERS,
  1416. RegCountFromIndex(regnum));
  1417. return TRUE;
  1418. }
  1419. void
  1420. Ia64MachineInfo::GetPC (PADDR Address)
  1421. {
  1422. ULONG64 value, slot;
  1423. // get slot# from IPSR.ri and place them in bit(2-3)
  1424. slot = (GetReg64(STIPSR) >> (PSR_RI - 2)) & 0xc;
  1425. // Do not use ISR.ei which does not contain the restart instruction slot.
  1426. value = GetReg64(STIIP) | slot;
  1427. ADDRFLAT(Address, value);
  1428. }
  1429. void
  1430. Ia64MachineInfo::SetPC (PADDR paddr)
  1431. {
  1432. SetReg64(STIIP, Flat(*paddr));
  1433. }
  1434. void
  1435. Ia64MachineInfo::GetFP(PADDR Address)
  1436. {
  1437. // IA64 software convention has no frame pointer defined.
  1438. // FP_REG need to be derived from virtual unwind of stack.
  1439. DEBUG_STACK_FRAME StackFrame;
  1440. StackTrace( 0, 0, 0, &StackFrame, 1, 0, 0, FALSE );
  1441. ADDRFLAT(Address, StackFrame.FrameOffset);
  1442. }
  1443. void
  1444. Ia64MachineInfo::GetSP(PADDR Address)
  1445. {
  1446. ADDRFLAT(Address, GetReg64(INTSP));
  1447. }
  1448. ULONG64
  1449. Ia64MachineInfo::GetArgReg(void)
  1450. {
  1451. return GetReg64(INTV0);
  1452. }
  1453. /*** RegOutputAll - output all registers and present instruction
  1454. *
  1455. * Purpose:
  1456. * Function of "r" command.
  1457. *
  1458. * To output the current register state of the processor.
  1459. * All integer registers are output as well as processor status
  1460. * registers in the _CONTEXT record. Important flag fields are
  1461. * also output separately. OutDisCurrent is called to output the
  1462. * current instruction(s).
  1463. *
  1464. * Input:
  1465. * None.
  1466. *
  1467. * Output:
  1468. * None.
  1469. *
  1470. *************************************************************************/
  1471. void
  1472. Ia64MachineInfo::OutputAll(ULONG Mask, ULONG OutMask)
  1473. {
  1474. int regindex, col = 0;
  1475. int lastout;
  1476. USHORT nStackReg;
  1477. REGVAL val;
  1478. ULONG i;
  1479. if (GetContextState(MCTX_FULL) != S_OK)
  1480. {
  1481. ErrOut("Unable to retrieve register information\n");
  1482. return;
  1483. }
  1484. // Output user debug registers
  1485. if (Mask & REGALL_DREG)
  1486. {
  1487. for (regindex = IA64_DBBASE;
  1488. regindex <= IA64_DBLAST;
  1489. regindex++)
  1490. {
  1491. MaskOut(OutMask, "%9s = %16I64x",
  1492. RegNameFromIndex(regindex),
  1493. GetReg64(regindex));
  1494. if (regindex % 2 == 1)
  1495. {
  1496. MaskOut(OutMask, "\n");
  1497. }
  1498. else
  1499. {
  1500. MaskOut(OutMask, "\t");
  1501. }
  1502. }
  1503. MaskOut(OutMask, "\n");
  1504. }
  1505. if (Mask & (REGALL_INT32 | REGALL_INT64))
  1506. {
  1507. if (Mask & REGALL_SPECIALREG)
  1508. {
  1509. // + ARs + DBs + SRs
  1510. lastout = IA64_SREND + 1;
  1511. }
  1512. else
  1513. {
  1514. // INTs, PREDS, BRs,
  1515. lastout = IA64_SRBASE;
  1516. }
  1517. nStackReg = (USHORT)(GetReg64(STIFS) & 0x7F);
  1518. // Output all registers, skip INTZERO and floating point registers
  1519. for (regindex = IA64_REGBASE; regindex < lastout; regindex++)
  1520. {
  1521. if (regindex == BRRP || regindex == PREDS || regindex == APUNAT ||
  1522. regindex == IA64_SRBASE || regindex == INTR32)
  1523. {
  1524. if (col % 2 == 1)
  1525. {
  1526. MaskOut(OutMask, "\n");
  1527. }
  1528. MaskOut(OutMask, "\n");
  1529. col = 0;
  1530. }
  1531. if (INTGP <= regindex && regindex <= INTT22)
  1532. {
  1533. if (GetVal(regindex, &val))
  1534. {
  1535. MaskOut(OutMask, "%9s = %16I64x %1lx",
  1536. RegNameFromIndex(regindex),
  1537. val.i64, val.Nat);
  1538. }
  1539. if (col % 2 == 1)
  1540. {
  1541. MaskOut(OutMask, "\n");
  1542. }
  1543. else
  1544. {
  1545. MaskOut(OutMask, "\t");
  1546. }
  1547. col++;
  1548. }
  1549. else if (INTR32 <= regindex && regindex <= INTR127)
  1550. {
  1551. if ((nStackReg != 0) && GetVal(regindex, &val))
  1552. {
  1553. MaskOut(OutMask, "%9s = %16I64x %1lx",
  1554. RegNameFromIndex(regindex),
  1555. val.i64, val.Nat);
  1556. nStackReg--;
  1557. if (col % 2 == 1)
  1558. {
  1559. MaskOut(OutMask, "\n");
  1560. }
  1561. else
  1562. {
  1563. MaskOut(OutMask, "\t");
  1564. }
  1565. col++;
  1566. }
  1567. }
  1568. else
  1569. {
  1570. MaskOut(OutMask, "%9s = %16I64x",
  1571. RegNameFromIndex(regindex),
  1572. GetReg64(regindex));
  1573. if (col % 2 == 1)
  1574. {
  1575. MaskOut(OutMask, "\n");
  1576. }
  1577. else
  1578. {
  1579. MaskOut(OutMask, "\t");
  1580. }
  1581. col++;
  1582. }
  1583. }
  1584. MaskOut(OutMask, "\n");
  1585. /*
  1586. // Output IPSR flags
  1587. MaskOut(OutMask, "\n\tipsr:\tbn ed ri ss dd da id it tme is cpl rt tb lp db\n");
  1588. MaskOut(OutMask, "\t\t %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx\n",
  1589. GetSubReg32(IPSRBN),
  1590. GetSubReg32(IPSRED),
  1591. GetSubReg32(IPSRRI),
  1592. GetSubReg32(IPSRSS),
  1593. GetSubReg32(IPSRDD),
  1594. GetSubReg32(IPSRDA),
  1595. GetSubReg32(IPSRID),
  1596. GetSubReg32(IPSRIT),
  1597. GetSubReg32(IPSRME),
  1598. GetSubReg32(IPSRIS),
  1599. GetSubReg32(IPSRCPL),
  1600. GetSubReg32(IPSRRT),
  1601. GetSubReg32(IPSRTB),
  1602. GetSubReg32(IPSRLP),
  1603. GetSubReg32(IPSRDB));
  1604. MaskOut(OutMask, "\t\tsi di pp sp dfh dfl dt bn pk i ic ac up be or\n");
  1605. MaskOut(OutMask, "\t\t %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx %1lx\n",
  1606. GetSubReg32(IPSRSI),
  1607. GetSubReg32(IPSRDI),
  1608. GetSubReg32(IPSRPP),
  1609. GetSubReg32(IPSRSP),
  1610. GetSubReg32(IPSRDFH),
  1611. GetSubReg32(IPSRDFL),
  1612. GetSubReg32(IPSRDT),
  1613. GetSubReg32(IPSRPK),
  1614. GetSubReg32(IPSRI),
  1615. GetSubReg32(IPSRIC),
  1616. GetSubReg32(IPSRAC),
  1617. GetSubReg32(IPSRUP),
  1618. GetSubReg32(IPSRBE),
  1619. GetSubReg32(IPSROR));
  1620. */
  1621. }
  1622. if (Mask & REGALL_FLOAT)
  1623. {
  1624. /*
  1625. // Output FPSR flags
  1626. MaskOut(OutMask, "\n\tfpsr:\tmdh mdl sf3 sf2 sf1 sf0 id ud od zd dd vd\n");
  1627. MaskOut(OutMask, "\t\t %1lx %1lx %04lx %04lx %04lx %04lx %1lx %1lx %1lx %1lx %1lx %1lx\n",
  1628. GetSubReg32(FPSRMDH),
  1629. GetSubReg32(FPSRMDL),
  1630. GetSubReg32(FPSRSF3),
  1631. GetSubReg32(FPSRSF2),
  1632. GetSubReg32(FPSRSF1),
  1633. GetSubReg32(FPSRSF0),
  1634. GetSubReg32(FPSRTRAPID),
  1635. GetSubReg32(FPSRTRAPUD),
  1636. GetSubReg32(FPSRTRAPOD),
  1637. GetSubReg32(FPSRTRAPZD),
  1638. GetSubReg32(FPSRTRAPDD),
  1639. GetSubReg32(FPSRTRAPVD));
  1640. */
  1641. //
  1642. // Print the low floating point register set, skip FLTZERO & FLTONE
  1643. //
  1644. MaskOut(OutMask, "\n");
  1645. for (i = IA64_FLTBASE; i < FLTF32; i += 2)
  1646. {
  1647. GetVal(i, &val);
  1648. MaskOut(OutMask, "%9s = %I64x %I64x\n", RegNameFromIndex(i),
  1649. val.f16Parts.high, val.f16Parts.low);
  1650. }
  1651. }
  1652. if (Mask & REGALL_HIGHFLOAT)
  1653. {
  1654. //
  1655. // Print the low floating point register set, skip FLTZERO & FLTONE
  1656. //
  1657. MaskOut(OutMask, "\n");
  1658. for (i = FLTF32 ; i <= FLTF127; i += 2)
  1659. {
  1660. GetVal(i, &val);
  1661. MaskOut(OutMask, "%9s = %I64x %I64x\n", RegNameFromIndex(i),
  1662. val.f16Parts.high, val.f16Parts.low);
  1663. }
  1664. }
  1665. }
  1666. TRACEMODE
  1667. Ia64MachineInfo::GetTraceMode (void)
  1668. {
  1669. if (IS_KERNEL_TARGET())
  1670. {
  1671. return m_TraceMode;
  1672. }
  1673. else
  1674. {
  1675. ULONG64 Ipsr = GetReg64(STIPSR);
  1676. if (Ipsr & (1I64 << PSR_SS))
  1677. {
  1678. return TRACE_INSTRUCTION;
  1679. }
  1680. else if (Ipsr & (1I64 << PSR_TB))
  1681. {
  1682. return TRACE_TAKEN_BRANCH;
  1683. }
  1684. else
  1685. {
  1686. return TRACE_NONE;
  1687. }
  1688. }
  1689. }
  1690. void
  1691. Ia64MachineInfo::SetTraceMode (TRACEMODE Mode)
  1692. {
  1693. DBG_ASSERT(Mode == TRACE_NONE ||
  1694. Mode == TRACE_INSTRUCTION ||
  1695. Mode == TRACE_TAKEN_BRANCH);
  1696. if (IS_KERNEL_TARGET())
  1697. {
  1698. m_TraceMode = Mode;
  1699. }
  1700. else
  1701. {
  1702. ULONG64 Ipsr, IpsrSave;
  1703. Ipsr = IpsrSave = GetReg64(STIPSR);
  1704. Ipsr &= ~(1I64 << PSR_SS);
  1705. Ipsr &= ~(1I64 << PSR_TB);
  1706. switch (Mode)
  1707. {
  1708. case TRACE_INSTRUCTION:
  1709. Ipsr |= (1I64 << PSR_SS);
  1710. break;
  1711. case TRACE_TAKEN_BRANCH:
  1712. Ipsr |= (1I64 << PSR_TB);
  1713. break;
  1714. }
  1715. if (Ipsr != IpsrSave)
  1716. {
  1717. SetReg64(STIPSR, Ipsr);
  1718. }
  1719. }
  1720. }
  1721. BOOL
  1722. Ia64MachineInfo::IsStepStatusSupported(ULONG Status)
  1723. {
  1724. switch (Status)
  1725. {
  1726. case DEBUG_STATUS_STEP_INTO: // TRACE_INSTRUCTION
  1727. case DEBUG_STATUS_STEP_OVER:
  1728. case DEBUG_STATUS_STEP_BRANCH: // TRACE_TAKEN_BRANCH
  1729. return TRUE;
  1730. default:
  1731. return FALSE;
  1732. }
  1733. }
  1734. void
  1735. Ia64MachineInfo::KdUpdateControlSet
  1736. (PDBGKD_ANY_CONTROL_SET ControlSet)
  1737. {
  1738. switch (GetTraceMode())
  1739. {
  1740. case TRACE_NONE:
  1741. ControlSet->IA64ControlSet.Continue =
  1742. IA64_DBGKD_CONTROL_SET_CONTINUE_NONE;
  1743. break;
  1744. case TRACE_INSTRUCTION:
  1745. ControlSet->IA64ControlSet.Continue =
  1746. IA64_DBGKD_CONTROL_SET_CONTINUE_TRACE_INSTRUCTION;
  1747. break;
  1748. case TRACE_TAKEN_BRANCH:
  1749. ControlSet->IA64ControlSet.Continue =
  1750. IA64_DBGKD_CONTROL_SET_CONTINUE_TRACE_TAKEN_BRANCH;
  1751. break;
  1752. }
  1753. if (!g_WatchFunctions.IsStarted() && g_WatchBeginCurFunc != 1)
  1754. {
  1755. ControlSet->IA64ControlSet.CurrentSymbolStart = 0;
  1756. ControlSet->IA64ControlSet.CurrentSymbolEnd = 0;
  1757. }
  1758. else
  1759. {
  1760. ControlSet->IA64ControlSet.CurrentSymbolStart = g_WatchBeginCurFunc;
  1761. ControlSet->IA64ControlSet.CurrentSymbolEnd = g_WatchEndCurFunc;
  1762. }
  1763. }
  1764. void
  1765. Ia64MachineInfo::KdSaveProcessorState(
  1766. void
  1767. )
  1768. {
  1769. MachineInfo::KdSaveProcessorState();
  1770. m_SavedSpecialRegContext = m_SpecialRegContext;
  1771. }
  1772. void
  1773. Ia64MachineInfo::KdRestoreProcessorState(
  1774. void
  1775. )
  1776. {
  1777. MachineInfo::KdRestoreProcessorState();
  1778. m_SpecialRegContext = m_SavedSpecialRegContext;
  1779. }
  1780. ULONG
  1781. Ia64MachineInfo::ExecutingMachine(void)
  1782. {
  1783. if (IsIA32InstructionSet())
  1784. {
  1785. return IMAGE_FILE_MACHINE_I386;
  1786. }
  1787. return IMAGE_FILE_MACHINE_IA64;
  1788. }
  1789. HRESULT
  1790. Ia64MachineInfo::SetPageDirectory(ULONG Idx, ULONG64 PageDir,
  1791. PULONG NextIdx)
  1792. {
  1793. HRESULT Status;
  1794. switch(Idx)
  1795. {
  1796. case PAGE_DIR_USER:
  1797. if (PageDir == 0)
  1798. {
  1799. if ((Status = g_Target->ReadImplicitProcessInfoPointer
  1800. (m_OffsetEprocessDirectoryTableBase, &PageDir)) != S_OK)
  1801. {
  1802. return Status;
  1803. }
  1804. }
  1805. *NextIdx = PAGE_DIR_SESSION;
  1806. break;
  1807. case PAGE_DIR_SESSION:
  1808. if (PageDir == 0)
  1809. {
  1810. if ((Status = g_Target->
  1811. ReadImplicitProcessInfoPointer
  1812. (g_Machine->m_OffsetEprocessDirectoryTableBase +
  1813. 5 * sizeof(ULONG64), &PageDir)) != S_OK)
  1814. {
  1815. return Status;
  1816. }
  1817. }
  1818. *NextIdx = PAGE_DIR_KERNEL;
  1819. break;
  1820. case PAGE_DIR_KERNEL:
  1821. if (PageDir == 0)
  1822. {
  1823. PageDir = m_KernPageDir;
  1824. if (PageDir == 0)
  1825. {
  1826. ErrOut("Invalid IA64 kernel page directory base 0x%I64x\n",
  1827. PageDir);
  1828. return E_FAIL;
  1829. }
  1830. }
  1831. *NextIdx = PAGE_DIR_COUNT;
  1832. break;
  1833. case 4:
  1834. // There's a directly mapped physical section for
  1835. // most of region 4 so allow the default to be
  1836. // set for this directory index.
  1837. if (PageDir != 0)
  1838. {
  1839. return E_INVALIDARG;
  1840. }
  1841. *NextIdx = 5;
  1842. break;
  1843. default:
  1844. return E_INVALIDARG;
  1845. }
  1846. // Sanitize the value.
  1847. m_PageDirectories[Idx] =
  1848. ((PageDir & IA64_VALID_PFN_MASK) >> IA64_VALID_PFN_SHIFT) <<
  1849. IA64_PAGE_SHIFT;
  1850. return S_OK;
  1851. }
  1852. #define IA64_PAGE_FILE_INDEX(Entry) \
  1853. (((ULONG)(Entry) >> 28) & MAX_PAGING_FILE_MASK)
  1854. #define IA64_PAGE_FILE_OFFSET(Entry) \
  1855. (((Entry) >> 32) << IA64_PAGE_SHIFT)
  1856. HRESULT
  1857. Ia64MachineInfo::GetVirtualTranslationPhysicalOffsets(ULONG64 Virt,
  1858. PULONG64 Offsets,
  1859. ULONG OffsetsSize,
  1860. PULONG Levels,
  1861. PULONG PfIndex,
  1862. PULONG64 LastVal)
  1863. {
  1864. HRESULT Status;
  1865. *Levels = 0;
  1866. if (m_Translating)
  1867. {
  1868. return E_UNEXPECTED;
  1869. }
  1870. m_Translating = TRUE;
  1871. ULONG Vrn = (ULONG)((Virt & IA64_REGION_MASK) >> IA64_REGION_SHIFT);
  1872. //
  1873. // Reset the page directory in case it was 0
  1874. //
  1875. if (m_PageDirectories[Vrn] == 0)
  1876. {
  1877. if ((Status = SetDefaultPageDirectories(1 << Vrn)) != S_OK)
  1878. {
  1879. m_Translating = FALSE;
  1880. return Status;
  1881. }
  1882. }
  1883. KdOut("Ia64VtoP: Virt %s, pagedir %d:%s\n",
  1884. FormatAddr64(Virt), Vrn, FormatAddr64(m_PageDirectories[Vrn]));
  1885. (*Levels)++;
  1886. if (Offsets != NULL && OffsetsSize > 0)
  1887. {
  1888. *Offsets++ = m_PageDirectories[Vrn];
  1889. OffsetsSize--;
  1890. }
  1891. //
  1892. // Certain ranges of the system are mapped directly.
  1893. //
  1894. if ((Virt >= IA64_PHYSICAL1_START) && (Virt <= IA64_PHYSICAL1_END))
  1895. {
  1896. *LastVal = Virt - IA64_PHYSICAL1_START;
  1897. KdOut("Ia64VtoP: Direct phys 1 %s\n", FormatAddr64(*LastVal));
  1898. (*Levels)++;
  1899. if (Offsets != NULL && OffsetsSize > 0)
  1900. {
  1901. *Offsets++ = *LastVal;
  1902. OffsetsSize--;
  1903. }
  1904. m_Translating = FALSE;
  1905. return S_OK;
  1906. }
  1907. if ((Virt >= IA64_PHYSICAL2_START) && (Virt <= IA64_PHYSICAL2_END))
  1908. {
  1909. *LastVal = Virt - IA64_PHYSICAL2_START;
  1910. KdOut("Ia64VtoP: Direct phys 2 %s\n", FormatAddr64(*LastVal));
  1911. (*Levels)++;
  1912. if (Offsets != NULL && OffsetsSize > 0)
  1913. {
  1914. *Offsets++ = *LastVal;
  1915. OffsetsSize--;
  1916. }
  1917. m_Translating = FALSE;
  1918. return S_OK;
  1919. }
  1920. // If we're still translating and there's no page
  1921. // directory we have a garbage address.
  1922. if (m_PageDirectories[Vrn] == 0)
  1923. {
  1924. m_Translating = FALSE;
  1925. return HR_PAGE_NOT_AVAILABLE;
  1926. }
  1927. ULONG64 Addr;
  1928. ULONG64 Entry;
  1929. Addr = (((Virt >> IA64_PDE1_SHIFT) & IA64_PDE_MASK) * sizeof(Entry)) +
  1930. m_PageDirectories[Vrn];
  1931. Status = g_Target->ReadAllPhysical(Addr, &Entry, sizeof(Entry));
  1932. KdOut("Ia64VtoP: PDE1 %s - %016I64x, 0x%X\n",
  1933. FormatAddr64(Addr), Entry, Status);
  1934. (*Levels)++;
  1935. if (Offsets != NULL && OffsetsSize > 0)
  1936. {
  1937. *Offsets++ = Addr;
  1938. OffsetsSize--;
  1939. }
  1940. if (Status != S_OK)
  1941. {
  1942. KdOut("Ia64VtoP: PDE1 read error 0x%X\n", Status);
  1943. m_Translating = FALSE;
  1944. return Status;
  1945. }
  1946. if (Entry == 0)
  1947. {
  1948. KdOut("Ia64VtoP: zero PDE1\n");
  1949. m_Translating = FALSE;
  1950. return HR_PAGE_NOT_AVAILABLE;
  1951. }
  1952. else if (!(Entry & 1))
  1953. {
  1954. Addr = (((Virt >> IA64_PDE2_SHIFT) & IA64_PDE_MASK) *
  1955. sizeof(Entry)) + IA64_PAGE_FILE_OFFSET(Entry);
  1956. KdOut("Ia64VtoP: pagefile PDE2 %d:%s\n",
  1957. IA64_PAGE_FILE_INDEX(Entry), FormatAddr64(Addr));
  1958. if ((Status = g_Target->
  1959. ReadPageFile(IA64_PAGE_FILE_INDEX(Entry), Addr,
  1960. &Entry, sizeof(Entry))) != S_OK)
  1961. {
  1962. KdOut("Ia64VtoP: PDE1 not present, 0x%X\n", Status);
  1963. m_Translating = FALSE;
  1964. return Status;
  1965. }
  1966. }
  1967. else
  1968. {
  1969. Addr = (((Virt >> IA64_PDE2_SHIFT) & IA64_PDE_MASK) * sizeof(Entry)) +
  1970. (((Entry & IA64_VALID_PFN_MASK) >> IA64_VALID_PFN_SHIFT) <<
  1971. IA64_PAGE_SHIFT);
  1972. Status = g_Target->ReadAllPhysical(Addr, &Entry, sizeof(Entry));
  1973. KdOut("Ia64VtoP: PDE2 %s - %016I64x, 0x%X\n",
  1974. FormatAddr64(Addr), Entry, Status);
  1975. (*Levels)++;
  1976. if (Offsets != NULL && OffsetsSize > 0)
  1977. {
  1978. *Offsets++ = Addr;
  1979. OffsetsSize--;
  1980. }
  1981. if (Status != S_OK)
  1982. {
  1983. KdOut("Ia64VtoP: PDE2 read error 0x%X\n", Status);
  1984. m_Translating = FALSE;
  1985. return Status;
  1986. }
  1987. }
  1988. if (Entry == 0)
  1989. {
  1990. KdOut("Ia64VtoP: zero PDE2\n");
  1991. m_Translating = FALSE;
  1992. return HR_PAGE_NOT_AVAILABLE;
  1993. }
  1994. else if (!(Entry & 1))
  1995. {
  1996. Addr = (((Virt >> IA64_PTE_SHIFT) & IA64_PTE_MASK) *
  1997. sizeof(Entry)) + IA64_PAGE_FILE_OFFSET(Entry);
  1998. KdOut("Ia64VtoP: pagefile PTE %d:%s\n",
  1999. IA64_PAGE_FILE_INDEX(Entry), FormatAddr64(Addr));
  2000. if ((Status = g_Target->
  2001. ReadPageFile(IA64_PAGE_FILE_INDEX(Entry), Addr,
  2002. &Entry, sizeof(Entry))) != S_OK)
  2003. {
  2004. KdOut("Ia64VtoP: PDE2 not present, 0x%X\n", Status);
  2005. m_Translating = FALSE;
  2006. return Status;
  2007. }
  2008. }
  2009. else
  2010. {
  2011. Addr = (((Virt >> IA64_PTE_SHIFT) & IA64_PTE_MASK) * sizeof(Entry)) +
  2012. (((Entry & IA64_VALID_PFN_MASK) >> IA64_VALID_PFN_SHIFT) <<
  2013. IA64_PAGE_SHIFT);
  2014. Status = g_Target->ReadAllPhysical(Addr, &Entry, sizeof(Entry));
  2015. KdOut("Ia64VtoP: PTE %s - %016I64x, 0x%X\n",
  2016. FormatAddr64(Addr), Entry, Status);
  2017. (*Levels)++;
  2018. if (Offsets != NULL && OffsetsSize > 0)
  2019. {
  2020. *Offsets++ = Addr;
  2021. OffsetsSize--;
  2022. }
  2023. if (Status != S_OK)
  2024. {
  2025. KdOut("Ia64VtoP: PTE read error 0x%X\n", Status);
  2026. m_Translating = FALSE;
  2027. return Status;
  2028. }
  2029. }
  2030. if (!(Entry & 0x1) &&
  2031. ((Entry & IA64_MM_PTE_PROTOTYPE_MASK) ||
  2032. !(Entry & IA64_MM_PTE_TRANSITION_MASK)))
  2033. {
  2034. if (Entry == 0)
  2035. {
  2036. KdOut("Ia64VtoP: zero PTE\n");
  2037. Status = HR_PAGE_NOT_AVAILABLE;
  2038. }
  2039. else if (Entry & IA64_MM_PTE_PROTOTYPE_MASK)
  2040. {
  2041. KdOut("Ia64VtoP: prototype PTE\n");
  2042. Status = HR_PAGE_NOT_AVAILABLE;
  2043. }
  2044. else
  2045. {
  2046. *PfIndex = IA64_PAGE_FILE_INDEX(Entry);
  2047. *LastVal = (Virt & (IA64_PAGE_SIZE - 1)) +
  2048. IA64_PAGE_FILE_OFFSET(Entry);
  2049. KdOut("Ia64VtoP: PTE not present, pagefile %d:%s\n",
  2050. *PfIndex, FormatAddr64(*LastVal));
  2051. Status = HR_PAGE_IN_PAGE_FILE;
  2052. }
  2053. m_Translating = FALSE;
  2054. return Status;
  2055. }
  2056. //
  2057. // This is a page which is either present or in transition.
  2058. // Return the physical address for the request virtual address.
  2059. //
  2060. *LastVal = (((Entry & IA64_VALID_PFN_MASK) >> IA64_VALID_PFN_SHIFT) <<
  2061. IA64_PAGE_SHIFT) | (Virt & (IA64_PAGE_SIZE - 1));
  2062. KdOut("Ia64VtoP: Mapped phys %s\n", FormatAddr64(*LastVal));
  2063. (*Levels)++;
  2064. if (Offsets != NULL && OffsetsSize > 0)
  2065. {
  2066. *Offsets++ = *LastVal;
  2067. OffsetsSize--;
  2068. }
  2069. m_Translating = FALSE;
  2070. return S_OK;
  2071. }
  2072. HRESULT
  2073. Ia64MachineInfo::GetBaseTranslationVirtualOffset(PULONG64 Offset)
  2074. {
  2075. if (IS_LOCAL_KERNEL_TARGET())
  2076. {
  2077. CROSS_PLATFORM_KSPECIAL_REGISTERS Special;
  2078. HRESULT Status;
  2079. // We can't actually load a context when
  2080. // local kernel debugging but we can
  2081. // read the special registers and get
  2082. // the PTA value from there.
  2083. if ((Status = g_Target->GetTargetSpecialRegisters
  2084. (VIRTUAL_THREAD_HANDLE(0), &Special)) != S_OK)
  2085. {
  2086. return Status;
  2087. }
  2088. *Offset = Special.IA64Special.ApPTA;
  2089. }
  2090. else
  2091. {
  2092. *Offset = GetReg64(APPTA);
  2093. if (*Offset == 0)
  2094. {
  2095. return E_FAIL;
  2096. }
  2097. }
  2098. return S_OK;
  2099. }
  2100. #define HIGH128(x) (((FLOAT128 *)(&x))->HighPart)
  2101. #define LOW128(x) (((FLOAT128 *)(&x))->LowPart)
  2102. #define HIGHANDLOW128(x) HIGH128(x), LOW128(x)
  2103. BOOL
  2104. Ia64MachineInfo::DisplayTrapFrame(ULONG64 FrameAddress,
  2105. OUT PCROSS_PLATFORM_CONTEXT Context)
  2106. {
  2107. IA64_KTRAP_FRAME TrapContents;
  2108. ULONG64 Address=FrameAddress, IntSp;
  2109. ULONG result;
  2110. DWORD64 DisasmAddr;
  2111. DWORD64 Displacement;
  2112. DWORD64 Bsp, RealBsp;
  2113. DWORD SizeOfFrame;
  2114. DWORD i;
  2115. SHORT temp, j;
  2116. CHAR Buffer[80];
  2117. ULONG64 StIIP, StISR;
  2118. if ( g_Target->ReadVirtual(Address, &TrapContents, sizeof(IA64_KTRAP_FRAME), &result) != S_OK)
  2119. {
  2120. dprintf("unable to get trap frame contents\n");
  2121. return FALSE;
  2122. }
  2123. dprintf("f6 (ft0) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT0) );
  2124. dprintf("f7 (ft1) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT1));
  2125. dprintf("f8 (ft2) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT2));
  2126. dprintf("f9 (ft3) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT3));
  2127. dprintf("f10 (ft3) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT4));
  2128. dprintf("f11 (ft4) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT5));
  2129. dprintf("f12 (ft5) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT6));
  2130. dprintf("f13 (ft6) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT7));
  2131. dprintf("f14 (ft7) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT8));
  2132. dprintf("f15 (ft8) =\t %016I64x %016I64x\n" , HIGHANDLOW128(TrapContents.FltT9));
  2133. dprintf("unat =\t %016I64lx\t", TrapContents.ApUNAT);
  2134. dprintf("ccv =\t %016I64lx\n" , TrapContents.ApCCV);
  2135. dprintf("dcr =\t %016I64lx\t" , TrapContents.ApDCR);
  2136. dprintf("preds =\t %016I64lx\n",TrapContents.Preds);
  2137. dprintf("rsc =\t %016I64lx\t", TrapContents.RsRSC);
  2138. SizeOfFrame = (ULONG)(TrapContents.StIFS & (IA64_PFS_SIZE_MASK));
  2139. if (TrapContents.PreviousMode == 1 /*UserMode*/)
  2140. {
  2141. ULONG64 RsBSPSTORE=TrapContents.RsBSPSTORE;
  2142. dprintf("rnat =\t %016I64lx\n", TrapContents.RsRNAT);
  2143. dprintf("bspstore=%016I64lx\n", RsBSPSTORE);
  2144. //
  2145. // Calculate where the stacked registers are for the function which trapped.
  2146. // The regisisters are stored in the kernel backing store notCalculated the users.
  2147. // First calculate the start of the kernel store based on trap address, since
  2148. // this is a user mode trap we should start at the begining of the kernel stack
  2149. // so just round up the trap address to a page size. Next calculate the actual
  2150. // BSP for the function. This depends on the BSP and BSPstore at the time of
  2151. // the trap. Note that the trap handle start the kernel backing store on the
  2152. // same alignment as the user's BSPstore.
  2153. //
  2154. //Calculated
  2155. // Round trap address to a page boundary. The should be the Initial kernel BSP.
  2156. //
  2157. Bsp = (Address + IA64_PAGE_SIZE - 1) & ~(DWORD64)(IA64_PAGE_SIZE - 1);
  2158. //
  2159. // Start the actual stack on the same bountry as the users.
  2160. //
  2161. Bsp += RsBSPSTORE & IA64_RNAT_ALIGNMENT;
  2162. //
  2163. // The BSP of the trap handler is right after all the user values have been
  2164. // saved. The unsaved user values is the differenc of BSP and BSPStore.
  2165. //
  2166. Bsp += TrapContents.RsBSP - RsBSPSTORE;
  2167. }
  2168. else
  2169. {
  2170. dprintf("rnat =\t ???????? ????????\n", TrapContents.RsRNAT);
  2171. dprintf("bspstore=???????? ????????\n", TrapContents.RsBSPSTORE);
  2172. //
  2173. // For kernel mode the actual BSP is saved.
  2174. //
  2175. Bsp = TrapContents.RsBSP;
  2176. }
  2177. //
  2178. // Now backup by the size of the faulting functions frame.
  2179. //
  2180. Bsp -= (SizeOfFrame * sizeof(ULONGLONG));
  2181. //
  2182. // Adjust for saved RNATs
  2183. //
  2184. temp = (SHORT)(Bsp >> 3) & IA64_NAT_BITS_PER_RNAT_REG;
  2185. temp += (SHORT)SizeOfFrame - IA64_NAT_BITS_PER_RNAT_REG;
  2186. while (temp >= 0)
  2187. {
  2188. Bsp -= sizeof(ULONGLONG);
  2189. temp -= IA64_NAT_BITS_PER_RNAT_REG;
  2190. }
  2191. dprintf("bsp =\t %016I64lx\t", TrapContents.RsBSP);
  2192. dprintf("Real bsp = %016I64lx\n", RealBsp = Bsp);
  2193. dprintf("r1 (gp) =\t %016I64lx\t" , TrapContents.IntGp);
  2194. dprintf("r2 (t0) =\t %016I64lx\n" , TrapContents.IntT0);
  2195. dprintf("r3 (t1) =\t %016I64lx\t" , TrapContents.IntT1);
  2196. dprintf("r8 (v0) =\t %016I64lx\n" , TrapContents.IntV0);
  2197. dprintf("r9 (t2) =\t %016I64lx\t" , TrapContents.IntT2);
  2198. dprintf("r10 (t3) =\t %016I64lx\n" , TrapContents.IntT3);
  2199. dprintf("r11 (t4) =\t %016I64lx\t" , TrapContents.IntT4);
  2200. dprintf("r12 (sp) =\t %016I64lx\n" , IntSp = TrapContents.IntSp);
  2201. dprintf("r13 (teb) =\t %016I64lx\t" , TrapContents.IntTeb);
  2202. dprintf("r14 (t5) =\t %016I64lx\n" , TrapContents.IntT5);
  2203. dprintf("r15 (t6) =\t %016I64lx\t" , TrapContents.IntT6);
  2204. dprintf("r16 (t7) =\t %016I64lx\n" , TrapContents.IntT7);
  2205. dprintf("r17 (t8) =\t %016I64lx\t" , TrapContents.IntT8);
  2206. dprintf("r18 (t9) =\t %016I64lx\n" , TrapContents.IntT9);
  2207. dprintf("r19 (t10) =\t %016I64lx\t" , TrapContents.IntT10);
  2208. dprintf("r20 (t11) =\t %016I64lx\n" , TrapContents.IntT11);
  2209. dprintf("r21 (t12) =\t %016I64lx\t" , TrapContents.IntT12);
  2210. dprintf("r22 (t13) =\t %016I64lx\n" , TrapContents.IntT13);
  2211. dprintf("r23 (t14) =\t %016I64lx\t" , TrapContents.IntT14);
  2212. dprintf("r24 (t15) =\t %016I64lx\n" , TrapContents.IntT15);
  2213. dprintf("r25 (t16) =\t %016I64lx\t" , TrapContents.IntT16);
  2214. dprintf("r26 (t17) =\t %016I64lx\n" , TrapContents.IntT17);
  2215. dprintf("r27 (t18) =\t %016I64lx\t" , TrapContents.IntT18);
  2216. dprintf("r28 (t19) =\t %016I64lx\n" , TrapContents.IntT19);
  2217. dprintf("r29 (t20) =\t %016I64lx\t" , TrapContents.IntT20);
  2218. dprintf("r30 (t21) =\t %016I64lx\n" , TrapContents.IntT21);
  2219. dprintf("r31 (t22) =\t %016I64lx\n" , TrapContents.IntT22);
  2220. //
  2221. // Print out the stack registers.
  2222. //
  2223. for ( i = 0; i < SizeOfFrame; Bsp += sizeof(ULONGLONG))
  2224. {
  2225. ULONGLONG reg;
  2226. //
  2227. // Skip the NAT values.
  2228. //
  2229. if ((Bsp & IA64_RNAT_ALIGNMENT) == IA64_RNAT_ALIGNMENT)
  2230. {
  2231. continue;
  2232. }
  2233. if ( g_Target->ReadVirtual( Bsp, &reg, sizeof(ULONGLONG), &result) )
  2234. {
  2235. dprintf("Cannot read backing register store at %16I64x\n", Bsp);
  2236. }
  2237. dprintf("r%d =\t\t %016I64lx", (i + 32), reg);
  2238. if ((i % 2) == 1)
  2239. {
  2240. dprintf("\n");
  2241. }
  2242. else
  2243. {
  2244. dprintf("\t");
  2245. }
  2246. i++;
  2247. }
  2248. dprintf("\n");
  2249. dprintf("b0 (brrp) =\t %016I64lx\n", TrapContents.BrRp);
  2250. dprintf("b6 (brt0) =\t %016I64lx\n", TrapContents.BrT0);
  2251. dprintf("b7 (brt1) =\t %016I64lx\n", TrapContents.BrT1);
  2252. dprintf("nats =\t %016I64lx\n", TrapContents.IntNats);
  2253. dprintf("pfs =\t %016I64lx\n", TrapContents.RsPFS);
  2254. dprintf("ipsr =\t %016I64lx\n", TrapContents.StIPSR);
  2255. dprintf("isr =\t %016I64lx\n" , (StISR = TrapContents.StISR));
  2256. dprintf("ifa =\t %016I64lx\n" , TrapContents.StIFA);
  2257. dprintf("iip =\t %016I64lx\n" , StIIP = TrapContents.StIIP);
  2258. dprintf("iipa =\t %016I64lx\n", TrapContents.StIIPA);
  2259. dprintf("ifs =\t %016I64lx\n" , TrapContents.StIFS);
  2260. dprintf("iim =\t %016I64lx\n" , TrapContents.StIIM);
  2261. dprintf("iha =\t %016I64lx\n" , TrapContents.StIHA);
  2262. dprintf("fpsr =\t\t %08lx\n" , TrapContents.StFPSR);
  2263. // iA32 status info ???
  2264. dprintf("oldirql =\t %08lx\n" , TrapContents.OldIrql);
  2265. dprintf("previousmode =\t %08lx\n" , TrapContents.PreviousMode);
  2266. dprintf("trapframe =\t %08lx\n" , TrapContents.TrapFrame);
  2267. ULONG TrapFrameType = (ULONG)(TrapContents.EOFMarker) & 0xf;
  2268. switch (TrapFrameType)
  2269. {
  2270. case IA64_SYSCALL_FRAME:
  2271. dprintf("Trap Type: syscall\n");
  2272. break;
  2273. case IA64_INTERRUPT_FRAME:
  2274. dprintf("Trap Type: interrupt\n");
  2275. break;
  2276. case IA64_EXCEPTION_FRAME:
  2277. dprintf("Trap Type: exception\n");
  2278. break;
  2279. case IA64_CONTEXT_FRAME:
  2280. dprintf("Trap Type: context\n");
  2281. break;
  2282. default:
  2283. dprintf("Trap Type: unknown\n");
  2284. break;
  2285. }
  2286. DisasmAddr = StIIP;
  2287. //
  2288. // Adjust for the bundle.
  2289. //
  2290. DisasmAddr += ((StISR >> 41) & 3) * 4;
  2291. GetSymbolStdCall(DisasmAddr, Buffer, sizeof(Buffer), &Displacement, NULL);
  2292. dprintf("\n%s+0x%I64x\n", Buffer, Displacement);
  2293. ADDR tempAddr;
  2294. BOOL ret;
  2295. Type(tempAddr) = ADDR_FLAT | FLAT_COMPUTED;
  2296. Off(tempAddr) = Flat(tempAddr) = DisasmAddr;
  2297. if (g_Machine->Disassemble(&tempAddr, Buffer, FALSE))
  2298. {
  2299. dprintf(Buffer);
  2300. }
  2301. else
  2302. {
  2303. dprintf("???????????????\n", DisasmAddr);
  2304. }
  2305. g_LastRegFrame.InstructionOffset = StIIP;
  2306. g_LastRegFrame.StackOffset = IntSp;
  2307. g_LastRegFrame.FrameOffset = RealBsp;
  2308. if (Context)
  2309. {
  2310. // Fill up the context struct
  2311. #define CPCXT(Fld) Context->IA64Context.Fld = TrapContents.Fld
  2312. CPCXT(BrRp); CPCXT(BrT0); CPCXT(BrT1);
  2313. CPCXT(FltT0); CPCXT(FltT1); CPCXT(FltT2); CPCXT(FltT3); CPCXT(FltT4);
  2314. CPCXT(FltT5); CPCXT(FltT6); CPCXT(FltT7); CPCXT(FltT8); CPCXT(FltT9);
  2315. CPCXT(ApUNAT); CPCXT(ApCCV); CPCXT(ApDCR); CPCXT(Preds);
  2316. CPCXT(RsRSC); CPCXT(RsRNAT); CPCXT(RsBSPSTORE); CPCXT(RsBSP); CPCXT(RsPFS);
  2317. CPCXT(StIPSR); CPCXT(StIIP); CPCXT(StIFS); CPCXT(StFPSR);
  2318. CPCXT(IntSp); CPCXT(IntGp); CPCXT(IntV0); CPCXT(IntTeb); CPCXT(IntNats);
  2319. CPCXT(IntT0); CPCXT(IntT1); CPCXT(IntT2); CPCXT(IntT3); CPCXT(IntT4);
  2320. CPCXT(IntT5); CPCXT(IntT6); CPCXT(IntT7); CPCXT(IntT8); CPCXT(IntT9);
  2321. CPCXT(IntT10); CPCXT(IntT11); CPCXT(IntT12); CPCXT(IntT13); CPCXT(IntT14);
  2322. CPCXT(IntT15); CPCXT(IntT16); CPCXT(IntT17); CPCXT(IntT18); CPCXT(IntT19);
  2323. CPCXT(IntT20); CPCXT(IntT21); CPCXT(IntT22);
  2324. Context->IA64Context.RsBSP = RealBsp; // Store the real Bsp
  2325. #undef CPCXT
  2326. }
  2327. return TRUE;
  2328. }
  2329. void
  2330. Ia64MachineInfo::ValidateCxr(PCROSS_PLATFORM_CONTEXT Context)
  2331. {
  2332. // XXX drewb - Why doesn't this do anything?
  2333. }
  2334. void
  2335. Ia64MachineInfo::OutputFunctionEntry(PVOID RawEntry)
  2336. {
  2337. PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY Entry =
  2338. (PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY)RawEntry;
  2339. dprintf("BeginAddress = %s\n",
  2340. FormatAddr64(Entry->BeginAddress));
  2341. dprintf("EndAddress = %s\n",
  2342. FormatAddr64(Entry->EndAddress));
  2343. dprintf("UnwindInfoAddress = %s\n",
  2344. FormatAddr64(Entry->UnwindInfoAddress));
  2345. }
  2346. HRESULT
  2347. Ia64MachineInfo::ReadDynamicFunctionTable(ULONG64 Table,
  2348. PULONG64 NextTable,
  2349. PULONG64 MinAddress,
  2350. PULONG64 MaxAddress,
  2351. PULONG64 BaseAddress,
  2352. PULONG64 TableData,
  2353. PULONG TableSize,
  2354. PWSTR OutOfProcessDll,
  2355. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable)
  2356. {
  2357. HRESULT Status;
  2358. if ((Status = g_Target->
  2359. ReadAllVirtual(Table, &RawTable->IA64Table,
  2360. sizeof(RawTable->IA64Table))) != S_OK)
  2361. {
  2362. return Status;
  2363. }
  2364. *NextTable = RawTable->IA64Table.Links.Flink;
  2365. *MinAddress = RawTable->IA64Table.MinimumAddress;
  2366. *MaxAddress = RawTable->IA64Table.MaximumAddress;
  2367. *BaseAddress = RawTable->IA64Table.BaseAddress;
  2368. if (RawTable->IA64Table.Type == IA64_RF_CALLBACK)
  2369. {
  2370. ULONG Done;
  2371. *TableData = 0;
  2372. *TableSize = 0;
  2373. if ((Status = g_Target->
  2374. ReadVirtual(RawTable->IA64Table.OutOfProcessCallbackDll,
  2375. OutOfProcessDll, (MAX_PATH - 1) * sizeof(WCHAR),
  2376. &Done)) != S_OK)
  2377. {
  2378. return Status;
  2379. }
  2380. OutOfProcessDll[Done / sizeof(WCHAR)] = 0;
  2381. }
  2382. else
  2383. {
  2384. *TableData = RawTable->IA64Table.FunctionTable;
  2385. *TableSize = RawTable->IA64Table.EntryCount *
  2386. sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
  2387. OutOfProcessDll[0] = 0;
  2388. }
  2389. return S_OK;
  2390. }
  2391. PVOID
  2392. Ia64MachineInfo::FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  2393. ULONG64 Address,
  2394. PVOID TableData,
  2395. ULONG TableSize)
  2396. {
  2397. ULONG i;
  2398. PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY Func;
  2399. static IMAGE_IA64_RUNTIME_FUNCTION_ENTRY s_RetFunc;
  2400. Func = (PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY)TableData;
  2401. for (i = 0; i < TableSize / sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY); i++)
  2402. {
  2403. if (Address >= IA64_RF_BEGIN_ADDRESS(Table->IA64Table.BaseAddress, Func) &&
  2404. Address < IA64_RF_END_ADDRESS(Table->IA64Table.BaseAddress, Func))
  2405. {
  2406. // The table data is temporary so copy the data into
  2407. // a static buffer for longer-term storage.
  2408. s_RetFunc.BeginAddress = Func->BeginAddress;
  2409. s_RetFunc.EndAddress = Func->EndAddress;
  2410. s_RetFunc.UnwindInfoAddress = Func->UnwindInfoAddress;
  2411. return (PVOID)&s_RetFunc;
  2412. }
  2413. Func++;
  2414. }
  2415. return NULL;
  2416. }
  2417. HRESULT
  2418. Ia64MachineInfo::ReadKernelProcessorId
  2419. (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id)
  2420. {
  2421. HRESULT Status;
  2422. ULONG64 Prcb, PrcbMember;
  2423. ULONG Data[4];
  2424. if ((Status = g_Target->
  2425. GetProcessorSystemDataOffset(Processor, DEBUG_DATA_KPRCB_OFFSET,
  2426. &Prcb)) != S_OK)
  2427. {
  2428. return Status;
  2429. }
  2430. PrcbMember = Prcb + FIELD_OFFSET(IA64_PARTIAL_KPRCB, ProcessorModel);
  2431. if ((Status = g_Target->
  2432. ReadAllVirtual(PrcbMember, Data, sizeof(Data))) != S_OK)
  2433. {
  2434. return Status;
  2435. }
  2436. Id->Ia64.Model = Data[0];
  2437. Id->Ia64.Revision = Data[1];
  2438. Id->Ia64.Family = Data[2];
  2439. Id->Ia64.ArchRev = Data[3];
  2440. PrcbMember = Prcb + FIELD_OFFSET(IA64_PARTIAL_KPRCB,
  2441. ProcessorVendorString);
  2442. if ((Status = g_Target->
  2443. ReadAllVirtual(PrcbMember, Id->Ia64.VendorString,
  2444. sizeof(Id->Ia64.VendorString))) != S_OK)
  2445. {
  2446. return Status;
  2447. }
  2448. return S_OK;
  2449. }
  2450. BOOL
  2451. Ia64MachineInfo::IsIA32InstructionSet(VOID)
  2452. {
  2453. return ((GetReg64(STIPSR) & (1I64 << PSR_IS)) ? TRUE : FALSE);
  2454. }
  2455. void
  2456. Ia64MachineInfo::KdGetSpecialRegistersFromContext(void)
  2457. {
  2458. DBG_ASSERT(m_ContextState >= MCTX_FULL);
  2459. memcpy(&m_SpecialRegContext.KernelDbI0, &m_Context.IA64Context.DbI0,
  2460. IA64_DB_COUNT * sizeof(ULONG64));
  2461. }
  2462. void
  2463. Ia64MachineInfo::KdSetSpecialRegistersInContext(void)
  2464. {
  2465. DBG_ASSERT(m_ContextState >= MCTX_FULL);
  2466. memcpy(&m_Context.IA64Context.DbI0, &m_SpecialRegContext.KernelDbI0,
  2467. IA64_DB_COUNT * sizeof(ULONG64));
  2468. }
  2469. BOOL
  2470. Ia64MachineInfo::GetStackedRegVal(
  2471. IN ULONG64 RsBSP,
  2472. IN USHORT FrameSize,
  2473. IN ULONG64 RsRNAT,
  2474. IN ULONG regnum,
  2475. OUT REGVAL *val
  2476. )
  2477. {
  2478. SHORT index;
  2479. SHORT temp;
  2480. ULONG result;
  2481. ULONG64 TargetAddress;
  2482. ULONG64 TargetNatAddress;
  2483. index = (SHORT)(RsBSP >> 3) & NAT_BITS_PER_RNAT_REG;
  2484. temp = index + (SHORT)FrameSize - NAT_BITS_PER_RNAT_REG;
  2485. while (temp >= 0) {
  2486. FrameSize++;
  2487. temp -= NAT_BITS_PER_RNAT_REG;
  2488. }
  2489. TargetAddress = RsBSP;
  2490. while (regnum > 0) {
  2491. regnum -= 1;
  2492. TargetAddress += 8;
  2493. if ((TargetAddress & 0x1F8) == 0x1F8) {
  2494. TargetAddress += 8;
  2495. }
  2496. }
  2497. if (g_Target->ReadVirtual(TargetAddress, (PUCHAR)&val->i64, 8,
  2498. &result) != S_OK ||
  2499. (result < 8))
  2500. {
  2501. ErrOut("unable to read memory location %I64x\n", TargetAddress);
  2502. return FALSE;
  2503. }
  2504. index = (SHORT)((TargetAddress - (TargetAddress & ~(0x1F8i64))) >> 3);
  2505. TargetNatAddress = TargetAddress | 0x1F8;
  2506. if (TargetNatAddress <= (RsBSP + (FrameSize * sizeof(ULONG64)))) {
  2507. //
  2508. // update backing store
  2509. //
  2510. if (g_Target->ReadVirtual(TargetNatAddress, (PUCHAR)&RsRNAT, 8,
  2511. &result) != S_OK || (result < 8))
  2512. {
  2513. ErrOut("unable to read memory location %I64x\n", TargetNatAddress);
  2514. return FALSE;
  2515. }
  2516. }
  2517. val->Nat = (UCHAR)(RsRNAT >> index) & 0x1;
  2518. return TRUE;
  2519. }
  2520. BOOL
  2521. Ia64MachineInfo::SetStackedRegVal(
  2522. IN ULONG64 RsBSP,
  2523. IN USHORT FrameSize,
  2524. IN ULONG64 *RsRNAT,
  2525. IN ULONG regnum,
  2526. IN REGVAL *val
  2527. )
  2528. {
  2529. SHORT index;
  2530. SHORT temp;
  2531. ULONG result;
  2532. ULONG64 Mask;
  2533. ULONG64 LocalRnat;
  2534. ULONG64 TargetAddress;
  2535. ULONG64 TargetNatAddress;
  2536. index = (SHORT)(RsBSP >> 3) & NAT_BITS_PER_RNAT_REG;
  2537. temp = index + (SHORT)FrameSize - NAT_BITS_PER_RNAT_REG;
  2538. while (temp >= 0) {
  2539. FrameSize++;
  2540. temp -= NAT_BITS_PER_RNAT_REG;
  2541. }
  2542. TargetAddress = RsBSP;
  2543. while (regnum > 0) {
  2544. regnum -= 1;
  2545. TargetAddress += 8;
  2546. if ((TargetAddress & 0x1F8) == 0x1F8) {
  2547. TargetAddress += 8;
  2548. }
  2549. }
  2550. if (g_Target->WriteVirtual(TargetAddress, &val->i64, 8, &result) != S_OK ||
  2551. (result < 8))
  2552. {
  2553. ErrOut("unable to write memory location %I64x\n", TargetAddress);
  2554. return FALSE;
  2555. }
  2556. index = (SHORT)((TargetAddress - (TargetAddress & ~(0x1F8i64))) >> 3);
  2557. TargetNatAddress = TargetAddress | 0x1F8;
  2558. Mask = 0x1i64 << index;
  2559. if (TargetNatAddress <= (RsBSP + (FrameSize * sizeof(ULONG64)))) {
  2560. if (g_Target->ReadVirtual(TargetNatAddress, (PUCHAR)&LocalRnat, 8,
  2561. &result) != S_OK || (result < 8))
  2562. {
  2563. ErrOut("unable to read memory location %I64x\n", TargetNatAddress);
  2564. return FALSE;
  2565. }
  2566. if (val->Nat) {
  2567. LocalRnat |= Mask;
  2568. } else {
  2569. LocalRnat &= ~Mask;
  2570. }
  2571. if (g_Target->WriteVirtual(TargetNatAddress, &LocalRnat, 8,
  2572. &result) != S_OK ||
  2573. (result < 8))
  2574. {
  2575. ErrOut("unable to write memory location %I64x\n",TargetNatAddress);
  2576. return FALSE;
  2577. }
  2578. } else {
  2579. if (val->Nat) {
  2580. *RsRNAT |= Mask;
  2581. } else {
  2582. *RsRNAT &= ~Mask;
  2583. }
  2584. }
  2585. return TRUE;
  2586. }
  2587. //----------------------------------------------------------------------------
  2588. //
  2589. // X86OnIa64MachineInfo.
  2590. //
  2591. //----------------------------------------------------------------------------
  2592. X86OnIa64MachineInfo g_X86OnIa64Machine;
  2593. HRESULT
  2594. X86OnIa64MachineInfo::InitializeForProcessor(void)
  2595. {
  2596. HRESULT Status = X86MachineInfo::InitializeForProcessor();
  2597. m_MaxDataBreakpoints = min(m_MaxDataBreakpoints,
  2598. IA64_REG_MAX_DATA_BREAKPOINTS);
  2599. return Status;
  2600. }
  2601. HRESULT
  2602. X86OnIa64MachineInfo::UdGetContextState(ULONG State)
  2603. {
  2604. HRESULT Status;
  2605. if ((Status = g_Ia64Machine.UdGetContextState(MCTX_FULL)) != S_OK)
  2606. {
  2607. return Status;
  2608. }
  2609. Ia64ContextToX86(&g_Ia64Machine.m_Context.IA64Context,
  2610. &m_Context.X86Nt5Context);
  2611. m_ContextState = MCTX_FULL;
  2612. return S_OK;
  2613. }
  2614. HRESULT
  2615. X86OnIa64MachineInfo::UdSetContext(void)
  2616. {
  2617. g_Ia64Machine.InitializeContextFlags(&g_Ia64Machine.m_Context,
  2618. g_SystemVersion);
  2619. X86ContextToIa64(&m_Context.X86Nt5Context,
  2620. &g_Ia64Machine.m_Context.IA64Context);
  2621. return g_Ia64Machine.UdSetContext();
  2622. }
  2623. HRESULT
  2624. X86OnIa64MachineInfo::KdGetContextState(ULONG State)
  2625. {
  2626. HRESULT Status;
  2627. dprintf("The context is partially valid. Only x86 user-mode context is available!\n");
  2628. if ((Status = g_Ia64Machine.KdGetContextState(MCTX_FULL)) != S_OK)
  2629. {
  2630. return Status;
  2631. }
  2632. Ia64ContextToX86(&g_Ia64Machine.m_Context.IA64Context,
  2633. &m_Context.X86Nt5Context);
  2634. m_ContextState = MCTX_FULL;
  2635. return S_OK;
  2636. }
  2637. HRESULT
  2638. X86OnIa64MachineInfo::KdSetContext(void)
  2639. {
  2640. dprintf("The context is partially valid. Only x86 user-mode context is available!\n");
  2641. g_Ia64Machine.InitializeContextFlags(&g_Ia64Machine.m_Context,
  2642. g_SystemVersion);
  2643. X86ContextToIa64(&m_Context.X86Nt5Context,
  2644. &g_Ia64Machine.m_Context.IA64Context);
  2645. return g_Ia64Machine.KdSetContext();
  2646. }
  2647. HRESULT
  2648. X86OnIa64MachineInfo::GetSegRegDescriptor(ULONG SegReg, PDESCRIPTOR64 Desc)
  2649. {
  2650. // XXX drewb - This should probably use the
  2651. // descriptor information embedded in the IA64 context.
  2652. ULONG RegNum = GetSegRegNum(SegReg);
  2653. if (RegNum == 0)
  2654. {
  2655. return E_INVALIDARG;
  2656. }
  2657. return EmulateNtSelDescriptor(this, GetIntReg(RegNum), Desc);
  2658. }
  2659. HRESULT
  2660. X86OnIa64MachineInfo::NewBreakpoint(DebugClient* Client,
  2661. ULONG Type,
  2662. ULONG Id,
  2663. Breakpoint** RetBp)
  2664. {
  2665. HRESULT Status;
  2666. switch(Type & (DEBUG_BREAKPOINT_CODE | DEBUG_BREAKPOINT_DATA))
  2667. {
  2668. case DEBUG_BREAKPOINT_CODE:
  2669. *RetBp = new CodeBreakpoint(Client, Id, IMAGE_FILE_MACHINE_I386);
  2670. Status = (*RetBp) ? S_OK : E_OUTOFMEMORY;
  2671. break;
  2672. case DEBUG_BREAKPOINT_DATA:
  2673. *RetBp = new X86OnIa64DataBreakpoint(Client, Id);
  2674. Status = (*RetBp) ? S_OK : E_OUTOFMEMORY;
  2675. break;
  2676. default:
  2677. // Unknown breakpoint type.
  2678. Status = E_NOINTERFACE;
  2679. }
  2680. return Status;
  2681. }
  2682. void X86OnIa64MachineInfo::InsertAllDataBreakpoints(void)
  2683. {
  2684. DBG_ASSERT(!&X86OnIa64MachineInfo::InsertAllDataBreakpoints);
  2685. }
  2686. void X86OnIa64MachineInfo::RemoveAllDataBreakpoints(void)
  2687. {
  2688. DBG_ASSERT(!&X86OnIa64MachineInfo::RemoveAllDataBreakpoints);
  2689. }
  2690. ULONG
  2691. X86OnIa64MachineInfo::IsBreakpointOrStepException(PEXCEPTION_RECORD64 Record,
  2692. ULONG FirstChance,
  2693. PADDR BpAddr,
  2694. PADDR RelAddr)
  2695. {
  2696. //
  2697. // XXX olegk - This is pure hack to eliminate need to map unavalable
  2698. // in 64-bit context ISR register to DR6.
  2699. // We using the fact that Code Breakpoint is recognized normally and
  2700. // for Data Breakpoint ISR register is avalable as 5th parameter of
  2701. // exception record.
  2702. //
  2703. ULONG Exbs =
  2704. X86MachineInfo::IsBreakpointOrStepException(Record,
  2705. FirstChance,
  2706. BpAddr, RelAddr);
  2707. if (Exbs == EXBS_BREAKPOINT_CODE)
  2708. {
  2709. return Exbs;
  2710. }
  2711. if (Record->ExceptionCode == STATUS_WX86_SINGLE_STEP)
  2712. {
  2713. ULONG64 Isr = Record->ExceptionInformation[4]; // Trap code is 2 lower bytes
  2714. ULONG TrapCode = ULONG(Isr & ISR_CODE_MASK);
  2715. ULONG Vector = (ULONG)(Isr >> ISR_IA_VECTOR) & 0xff;
  2716. if (Vector != 1)
  2717. {
  2718. return EXBS_NONE;
  2719. }
  2720. if (Isr & (1 << ISR_TB_TRAP))
  2721. {
  2722. ADDRFLAT(RelAddr, Record->ExceptionInformation[3]);
  2723. return EXBS_STEP_BRANCH;
  2724. }
  2725. else if (Isr & (1 << ISR_SS_TRAP))
  2726. {
  2727. return EXBS_STEP_INSTRUCTION;
  2728. }
  2729. else {
  2730. if (Isr & ((ULONG64)1 << ISR_X)) // Exec Data Breakpoint
  2731. {
  2732. return EXBS_BREAKPOINT_DATA;
  2733. }
  2734. else // Data Breakpoint
  2735. {
  2736. for (int i = 0; i < 4; ++i)
  2737. {
  2738. if (TrapCode & (1 << (4 + i)))
  2739. {
  2740. ULONG Addr = GetReg32(X86_DR0 + i);
  2741. if (Addr)
  2742. {
  2743. ADDRFLAT(BpAddr, Addr);
  2744. return EXBS_BREAKPOINT_DATA;
  2745. }
  2746. }
  2747. }
  2748. }
  2749. }
  2750. }
  2751. return EXBS_NONE;
  2752. }
  2753. #define NUMBER_OF_387REGS (X86_ST_LAST - X86_ST_FIRST + 1)
  2754. #define NUMBER_OF_XMMI_REGS (X86_XMM_LAST - X86_XMM_FIRST + 1)
  2755. VOID
  2756. Wow64CopyFpFromIa64Byte16(
  2757. IN PVOID Byte16Fp,
  2758. IN OUT PVOID Byte10Fp,
  2759. IN ULONG NumRegs);
  2760. VOID
  2761. Wow64CopyFpToIa64Byte16(
  2762. IN PVOID Byte10Fp,
  2763. IN OUT PVOID Byte16Fp,
  2764. IN ULONG NumRegs);
  2765. VOID
  2766. Wow64CopyXMMIToIa64Byte16(
  2767. IN PVOID ByteXMMI,
  2768. IN OUT PVOID Byte16Fp,
  2769. IN ULONG NumRegs);
  2770. VOID
  2771. Wow64CopyXMMIFromIa64Byte16(
  2772. IN PVOID Byte16Fp,
  2773. IN OUT PVOID ByteXMMI,
  2774. IN ULONG NumRegs);
  2775. VOID
  2776. Wow64RotateFpTop(
  2777. IN ULONGLONG Ia64_FSR,
  2778. IN OUT FLOAT128 UNALIGNED *ia32FxSave);
  2779. VOID
  2780. Wow64CopyIa64FromSpill(
  2781. IN PFLOAT128 SpillArea,
  2782. IN OUT FLOAT128 UNALIGNED *ia64Fp,
  2783. IN ULONG NumRegs);
  2784. VOID
  2785. Wow64CopyIa64ToFill(
  2786. IN FLOAT128 UNALIGNED *ia64Fp,
  2787. IN OUT PFLOAT128 FillArea,
  2788. IN ULONG NumRegs);
  2789. BOOL
  2790. MapDbgSlotIa64ToX86(
  2791. UINT Slot,
  2792. ULONG64 Ipsr,
  2793. ULONG64 DbD,
  2794. ULONG64 DbD1,
  2795. ULONG64 DbI,
  2796. ULONG64 DbI1,
  2797. ULONG* Dr7,
  2798. ULONG* Dr);
  2799. void
  2800. MapDbgSlotX86ToIa64(
  2801. UINT Slot,
  2802. ULONG Dr7,
  2803. ULONG Dr,
  2804. ULONG64* Ipsr,
  2805. ULONG64* DbD,
  2806. ULONG64* DbD1,
  2807. ULONG64* DbI,
  2808. ULONG64* DbI1);
  2809. void
  2810. X86OnIa64MachineInfo::Ia64ContextToX86(
  2811. PIA64_CONTEXT ContextIa64,
  2812. PX86_NT5_CONTEXT ContextX86)
  2813. {
  2814. FLOAT128 tmpFloat[NUMBER_OF_387REGS];
  2815. ULONG Ia32ContextFlags = ContextX86->ContextFlags;
  2816. ULONG Tid = GetCurrentThreadId();
  2817. DebugClient* Client;
  2818. for (Client = g_Clients; Client != NULL; Client = Client->m_Next)
  2819. {
  2820. if (Client->m_ThreadId == Tid)
  2821. {
  2822. break;
  2823. }
  2824. }
  2825. DBG_ASSERT((Client!=NULL));
  2826. if (!g_Ia64Machine.IsIA32InstructionSet())
  2827. {
  2828. if (g_Wow64exts == NULL)
  2829. {
  2830. dprintf("Need to load wow64exts.dll to retrieve context!\n");
  2831. return;
  2832. }
  2833. (*g_Wow64exts)(WOW64EXTS_GET_CONTEXT,
  2834. (ULONG64)Client,
  2835. (ULONG64)ContextX86,
  2836. (ULONG64)NULL);
  2837. return;
  2838. }
  2839. if ((Ia32ContextFlags & VDMCONTEXT_CONTROL) == VDMCONTEXT_CONTROL)
  2840. {
  2841. //
  2842. // And the control stuff
  2843. //
  2844. ContextX86->Ebp = (ULONG)ContextIa64->IntTeb;
  2845. ContextX86->SegCs = X86_KGDT_R3_CODE|3;
  2846. ContextX86->Eip = (ULONG)ContextIa64->StIIP;
  2847. ContextX86->SegSs = X86_KGDT_R3_DATA|3;
  2848. ContextX86->Esp = (ULONG)ContextIa64->IntSp;
  2849. ContextX86->EFlags = (ULONG)ContextIa64->Eflag;
  2850. //
  2851. // Map single step flag (EFlags.tf = EFlags.tf || PSR.ss)
  2852. //
  2853. if (ContextIa64->StIPSR & (1I64 << PSR_SS))
  2854. {
  2855. ContextX86->EFlags |= X86_BIT_FLAGTF;
  2856. }
  2857. }
  2858. if ((Ia32ContextFlags & VDMCONTEXT_INTEGER) == VDMCONTEXT_INTEGER)
  2859. {
  2860. //
  2861. // Now for the integer state...
  2862. //
  2863. ContextX86->Edi = (ULONG)ContextIa64->IntT6;
  2864. ContextX86->Esi = (ULONG)ContextIa64->IntT5;
  2865. ContextX86->Ebx = (ULONG)ContextIa64->IntT4;
  2866. ContextX86->Edx = (ULONG)ContextIa64->IntT3;
  2867. ContextX86->Ecx = (ULONG)ContextIa64->IntT2;
  2868. ContextX86->Eax = (ULONG)ContextIa64->IntV0;
  2869. }
  2870. if ((Ia32ContextFlags & VDMCONTEXT_SEGMENTS) == VDMCONTEXT_SEGMENTS)
  2871. {
  2872. //
  2873. // These are constants (and constants are used on ia32->ia64
  2874. // transition, not saved values) so make our life easy...
  2875. //
  2876. ContextX86->SegGs = X86_KGDT_R3_DATA|3;
  2877. ContextX86->SegEs = X86_KGDT_R3_DATA|3;
  2878. ContextX86->SegDs = X86_KGDT_R3_DATA|3;
  2879. ContextX86->SegSs = X86_KGDT_R3_DATA|3;
  2880. ContextX86->SegFs = X86_KGDT_R3_TEB|3;
  2881. ContextX86->SegCs = X86_KGDT_R3_CODE|3;
  2882. }
  2883. if ((Ia32ContextFlags & VDMCONTEXT_EXTENDED_REGISTERS) ==
  2884. VDMCONTEXT_EXTENDED_REGISTERS)
  2885. {
  2886. PX86_FXSAVE_FORMAT xmmi =
  2887. (PX86_FXSAVE_FORMAT) ContextX86->ExtendedRegisters;
  2888. xmmi->ControlWord = (USHORT)(ContextIa64->StFCR & 0xffff);
  2889. xmmi->StatusWord = (USHORT)(ContextIa64->StFSR & 0xffff);
  2890. xmmi->TagWord = (USHORT)(ContextIa64->StFSR >> 16) & 0xffff;
  2891. xmmi->ErrorOpcode = (USHORT)(ContextIa64->StFIR >> 48);
  2892. xmmi->ErrorOffset = (ULONG) (ContextIa64->StFIR & 0xffffffff);
  2893. xmmi->ErrorSelector = (ULONG) (ContextIa64->StFIR >> 32);
  2894. xmmi->DataOffset = (ULONG) (ContextIa64->StFDR & 0xffffffff);
  2895. xmmi->DataSelector = (ULONG) (ContextIa64->StFDR >> 32);
  2896. xmmi->MXCsr = (ULONG) (ContextIa64->StFCR >> 32) & 0xffff;
  2897. //
  2898. // Copy over the FP registers. Even though this is the new
  2899. // FXSAVE format with 16-bytes for each register, need to
  2900. // convert from spill/fill format to 80-bit double extended format
  2901. //
  2902. Wow64CopyIa64FromSpill((PFLOAT128) &(ContextIa64->FltT2),
  2903. (PFLOAT128) xmmi->RegisterArea,
  2904. NUMBER_OF_387REGS);
  2905. //
  2906. // Rotate the registers appropriately
  2907. //
  2908. Wow64RotateFpTop(ContextIa64->StFSR, (PFLOAT128) xmmi->RegisterArea);
  2909. //
  2910. // Finally copy the xmmi registers
  2911. //
  2912. Wow64CopyXMMIFromIa64Byte16(&(ContextIa64->FltS4),
  2913. xmmi->Reserved3,
  2914. NUMBER_OF_XMMI_REGS);
  2915. }
  2916. if ((Ia32ContextFlags & VDMCONTEXT_FLOATING_POINT) ==
  2917. VDMCONTEXT_FLOATING_POINT)
  2918. {
  2919. //
  2920. // Copy over the floating point status/control stuff
  2921. //
  2922. ContextX86->FloatSave.ControlWord = (ULONG)(ContextIa64->StFCR & 0xffff);
  2923. ContextX86->FloatSave.StatusWord = (ULONG)(ContextIa64->StFSR & 0xffff);
  2924. ContextX86->FloatSave.TagWord = (ULONG)(ContextIa64->StFSR >> 16) & 0xffff;
  2925. ContextX86->FloatSave.ErrorOffset = (ULONG)(ContextIa64->StFIR & 0xffffffff);
  2926. ContextX86->FloatSave.ErrorSelector = (ULONG)(ContextIa64->StFIR >> 32);
  2927. ContextX86->FloatSave.DataOffset = (ULONG)(ContextIa64->StFDR & 0xffffffff);
  2928. ContextX86->FloatSave.DataSelector = (ULONG)(ContextIa64->StFDR >> 32);
  2929. //
  2930. // Copy over the FP registers into temporary space
  2931. // Even though this is the new
  2932. // FXSAVE format with 16-bytes for each register, need to
  2933. // convert from spill/fill format to 80-bit double extended format
  2934. //
  2935. Wow64CopyIa64FromSpill((PFLOAT128) &(ContextIa64->FltT2),
  2936. (PFLOAT128) tmpFloat,
  2937. NUMBER_OF_387REGS);
  2938. //
  2939. // Rotate the registers appropriately
  2940. //
  2941. Wow64RotateFpTop(ContextIa64->StFSR, tmpFloat);
  2942. //
  2943. // And put them in the older FNSAVE format (packed 10 byte values)
  2944. //
  2945. Wow64CopyFpFromIa64Byte16(tmpFloat,
  2946. ContextX86->FloatSave.RegisterArea,
  2947. NUMBER_OF_387REGS);
  2948. }
  2949. if ((Ia32ContextFlags & VDMCONTEXT_DEBUG_REGISTERS) ==
  2950. VDMCONTEXT_DEBUG_REGISTERS)
  2951. {
  2952. // Ia64 -> X86
  2953. BOOL Valid = TRUE;
  2954. Valid &= MapDbgSlotIa64ToX86(0, ContextIa64->StIPSR, ContextIa64->DbD0, ContextIa64->DbD1, ContextIa64->DbI0, ContextIa64->DbI1, &ContextX86->Dr7, &ContextX86->Dr0);
  2955. Valid &= MapDbgSlotIa64ToX86(1, ContextIa64->StIPSR, ContextIa64->DbD2, ContextIa64->DbD3, ContextIa64->DbI2, ContextIa64->DbI3, &ContextX86->Dr7, &ContextX86->Dr1);
  2956. Valid &= MapDbgSlotIa64ToX86(2, ContextIa64->StIPSR, ContextIa64->DbD4, ContextIa64->DbD5, ContextIa64->DbI4, ContextIa64->DbI5, &ContextX86->Dr7, &ContextX86->Dr2);
  2957. Valid &= MapDbgSlotIa64ToX86(3, ContextIa64->StIPSR, ContextIa64->DbD6, ContextIa64->DbD7, ContextIa64->DbI6, ContextIa64->DbI7, &ContextX86->Dr7, &ContextX86->Dr3);
  2958. if (!Valid)
  2959. {
  2960. WarnOut("Wasn't able to map IA64 debug registers consistently!!!\n");
  2961. }
  2962. //
  2963. // Map single step flag (EFlags.tf = EFlags.tf || PSR.ss)
  2964. //
  2965. if (ContextIa64->StIPSR & (1I64 << PSR_SS))
  2966. {
  2967. ContextX86->EFlags |= X86_BIT_FLAGTF;
  2968. }
  2969. }
  2970. }
  2971. void
  2972. X86OnIa64MachineInfo::X86ContextToIa64(
  2973. PX86_NT5_CONTEXT ContextX86,
  2974. PIA64_CONTEXT ContextIa64)
  2975. {
  2976. FLOAT128 tmpFloat[NUMBER_OF_387REGS];
  2977. ULONG Ia32ContextFlags = ContextX86->ContextFlags;
  2978. ULONG Tid = GetCurrentThreadId();
  2979. DebugClient* Client;
  2980. for (Client = g_Clients; Client != NULL; Client = Client->m_Next)
  2981. {
  2982. if (Client->m_ThreadId == Tid)
  2983. {
  2984. break;
  2985. }
  2986. }
  2987. DBG_ASSERT((Client!=NULL));
  2988. if (!g_Ia64Machine.IsIA32InstructionSet())
  2989. {
  2990. if (g_Wow64exts == NULL)
  2991. {
  2992. dprintf("Need to load wow64exts.dll to retrieve context!\n");
  2993. return;
  2994. }
  2995. (*g_Wow64exts)(WOW64EXTS_SET_CONTEXT,
  2996. (ULONG64)Client,
  2997. (ULONG64)ContextX86,
  2998. (ULONG64)NULL);
  2999. return;
  3000. }
  3001. if ((Ia32ContextFlags & VDMCONTEXT_CONTROL) == VDMCONTEXT_CONTROL)
  3002. {
  3003. //
  3004. // And the control stuff
  3005. //
  3006. ContextIa64->IntTeb = ContextX86->Ebp;
  3007. ContextIa64->StIIP = ContextX86->Eip;
  3008. ContextIa64->IntSp = ContextX86->Esp;
  3009. ContextIa64->Eflag = ContextX86->EFlags;
  3010. //
  3011. // Map single step flag (PSR.ss = PSR.ss || EFlags.tf)
  3012. //
  3013. if (ContextX86->EFlags & X86_BIT_FLAGTF)
  3014. {
  3015. ContextIa64->StIPSR |= (1I64 << PSR_SS);
  3016. }
  3017. //
  3018. // The segments (cs and ds) are a constant, so reset them.
  3019. // gr17 has LDT and TSS, so might as well reset
  3020. // all of them while we're at it...
  3021. // These values are forced in during a transition (see simulate.s)
  3022. // so there is no point to trying to get cute and actually
  3023. // pass in the values from the X86 context record
  3024. //
  3025. ContextIa64->IntT8 = ((X86_KGDT_LDT|3) << 32)
  3026. | ((X86_KGDT_R3_DATA|3) << 16)
  3027. | (X86_KGDT_R3_CODE|3);
  3028. }
  3029. if ((Ia32ContextFlags & VDMCONTEXT_INTEGER) == VDMCONTEXT_INTEGER)
  3030. {
  3031. //
  3032. // Now for the integer state...
  3033. //
  3034. ContextIa64->IntT6 = ContextX86->Edi;
  3035. ContextIa64->IntT5 = ContextX86->Esi;
  3036. ContextIa64->IntT4 = ContextX86->Ebx;
  3037. ContextIa64->IntT3 = ContextX86->Edx;
  3038. ContextIa64->IntT2 = ContextX86->Ecx;
  3039. ContextIa64->IntV0 = ContextX86->Eax;
  3040. }
  3041. if ((Ia32ContextFlags & VDMCONTEXT_SEGMENTS) == VDMCONTEXT_SEGMENTS)
  3042. {
  3043. //
  3044. // These are constants (and constants are used on ia32->ia64
  3045. // transition, not saved values) so make our life easy...
  3046. // These values are forced in during a transition (see simulate.s)
  3047. // so there is no point to trying to get cute and actually
  3048. // pass in the values from the X86 context record
  3049. //
  3050. ContextIa64->IntT7 = ((X86_KGDT_R3_DATA|3) << 48)
  3051. | ((X86_KGDT_R3_TEB|3) << 32)
  3052. | ((X86_KGDT_R3_DATA|3) << 16)
  3053. | (X86_KGDT_R3_DATA|3);
  3054. }
  3055. if ((Ia32ContextFlags & VDMCONTEXT_EXTENDED_REGISTERS) ==
  3056. VDMCONTEXT_EXTENDED_REGISTERS)
  3057. {
  3058. PX86_FXSAVE_FORMAT xmmi =
  3059. (PX86_FXSAVE_FORMAT) ContextX86->ExtendedRegisters;
  3060. //
  3061. // And copy over the floating point status/control stuff
  3062. //
  3063. ContextIa64->StFCR = (ContextIa64->StFCR & 0xffffffffffffe040i64) |
  3064. (xmmi->ControlWord & 0xffff) |
  3065. ((xmmi->MXCsr & 0xffff) << 32);
  3066. ContextIa64->StFSR = (ContextIa64->StFSR & 0xffffffff00000000i64) |
  3067. (xmmi->StatusWord & 0xffff) |
  3068. ((xmmi->TagWord & 0xffff) << 16);
  3069. ContextIa64->StFIR = (xmmi->ErrorOffset & 0xffffffff) |
  3070. (xmmi->ErrorSelector << 32);
  3071. ContextIa64->StFDR = (xmmi->DataOffset & 0xffffffff) |
  3072. (xmmi->DataSelector << 32);
  3073. //
  3074. // Don't touch the original ia32 context. Make a copy.
  3075. //
  3076. memcpy(tmpFloat, xmmi->RegisterArea,
  3077. NUMBER_OF_387REGS * sizeof(FLOAT128));
  3078. //
  3079. // Rotate registers back since st0 is not necessarily f8
  3080. //
  3081. {
  3082. ULONGLONG RotateFSR = (NUMBER_OF_387REGS -
  3083. ((ContextIa64->StFSR >> 11) & 0x7)) << 11;
  3084. Wow64RotateFpTop(RotateFSR, tmpFloat);
  3085. }
  3086. //
  3087. // Copy over the FP registers. Even though this is the new
  3088. // FXSAVE format with 16-bytes for each register, need to
  3089. // convert to spill/fill format from 80-bit double extended format
  3090. //
  3091. Wow64CopyIa64ToFill((PFLOAT128) tmpFloat,
  3092. (PFLOAT128) &(ContextIa64->FltT2),
  3093. NUMBER_OF_387REGS);
  3094. //
  3095. // Copy over the xmmi registers and convert them into a format
  3096. // that spill/fill can use
  3097. //
  3098. Wow64CopyXMMIToIa64Byte16(xmmi->Reserved3,
  3099. &(ContextIa64->FltS4),
  3100. NUMBER_OF_XMMI_REGS);
  3101. }
  3102. if ((Ia32ContextFlags & VDMCONTEXT_FLOATING_POINT) ==
  3103. VDMCONTEXT_FLOATING_POINT)
  3104. {
  3105. //
  3106. // Copy over the floating point status/control stuff
  3107. // Leave the MXCSR stuff alone
  3108. //
  3109. ContextIa64->StFCR = (ContextIa64->StFCR & 0xffffffffffffe040i64) |
  3110. (ContextX86->FloatSave.ControlWord & 0xffff);
  3111. ContextIa64->StFSR = (ContextIa64->StFSR & 0xffffffff00000000i64) |
  3112. (ContextX86->FloatSave.StatusWord & 0xffff) |
  3113. ((ContextX86->FloatSave.TagWord & 0xffff) << 16);
  3114. ContextIa64->StFIR = (ContextX86->FloatSave.ErrorOffset & 0xffffffff) |
  3115. (ContextX86->FloatSave.ErrorSelector << 32);
  3116. ContextIa64->StFDR = (ContextX86->FloatSave.DataOffset & 0xffffffff) |
  3117. (ContextX86->FloatSave.DataSelector << 32);
  3118. //
  3119. // Copy over the FP registers from packed 10-byte format
  3120. // to 16-byte format
  3121. //
  3122. Wow64CopyFpToIa64Byte16(ContextX86->FloatSave.RegisterArea,
  3123. tmpFloat,
  3124. NUMBER_OF_387REGS);
  3125. //
  3126. // Rotate registers back since st0 is not necessarily f8
  3127. //
  3128. {
  3129. ULONGLONG RotateFSR = (NUMBER_OF_387REGS -
  3130. ((ContextIa64->StFSR >> 11) & 0x7)) << 11;
  3131. Wow64RotateFpTop(RotateFSR, tmpFloat);
  3132. }
  3133. //
  3134. // Now convert from 80 bit extended format to fill/spill format
  3135. //
  3136. Wow64CopyIa64ToFill((PFLOAT128) tmpFloat,
  3137. (PFLOAT128) &(ContextIa64->FltT2),
  3138. NUMBER_OF_387REGS);
  3139. }
  3140. if ((Ia32ContextFlags & VDMCONTEXT_DEBUG_REGISTERS) ==
  3141. VDMCONTEXT_DEBUG_REGISTERS)
  3142. {
  3143. // X86 -> Ia64
  3144. MapDbgSlotX86ToIa64(0, ContextX86->Dr7, ContextX86->Dr0, &ContextIa64->StIPSR, &ContextIa64->DbD0, &ContextIa64->DbD1, &ContextIa64->DbI0, &ContextIa64->DbI1);
  3145. MapDbgSlotX86ToIa64(1, ContextX86->Dr7, ContextX86->Dr1, &ContextIa64->StIPSR, &ContextIa64->DbD2, &ContextIa64->DbD3, &ContextIa64->DbI2, &ContextIa64->DbI3);
  3146. MapDbgSlotX86ToIa64(2, ContextX86->Dr7, ContextX86->Dr2, &ContextIa64->StIPSR, &ContextIa64->DbD4, &ContextIa64->DbD5, &ContextIa64->DbI4, &ContextIa64->DbI5);
  3147. MapDbgSlotX86ToIa64(3, ContextX86->Dr7, ContextX86->Dr3, &ContextIa64->StIPSR, &ContextIa64->DbD6, &ContextIa64->DbD7, &ContextIa64->DbI6, &ContextIa64->DbI7);
  3148. //
  3149. // Map single step flag (PSR.ss = PSR.ss || EFlags.tf)
  3150. //
  3151. if (ContextX86->EFlags & X86_BIT_FLAGTF)
  3152. {
  3153. ContextIa64->StIPSR |= (1I64 << PSR_SS);
  3154. }
  3155. }
  3156. }
  3157. //
  3158. // Helper functions for context conversion
  3159. // --copied from \nt\base\wow64\cpu\context\context.c
  3160. //
  3161. //
  3162. // This allows the compiler to be more efficient in copying 10 bytes
  3163. // without over copying...
  3164. //
  3165. #pragma pack(push, 2)
  3166. typedef struct _ia32fpbytes {
  3167. ULONG significand_low;
  3168. ULONG significand_high;
  3169. USHORT exponent;
  3170. } IA32FPBYTES, *PIA32FPBYTES;
  3171. #pragma pack(pop)
  3172. VOID
  3173. Wow64CopyFpFromIa64Byte16(
  3174. IN PVOID Byte16Fp,
  3175. IN OUT PVOID Byte10Fp,
  3176. IN ULONG NumRegs)
  3177. {
  3178. ULONG i;
  3179. PIA32FPBYTES from, to;
  3180. from = (PIA32FPBYTES) Byte16Fp;
  3181. to = (PIA32FPBYTES) Byte10Fp;
  3182. for (i = 0; i < NumRegs; i++) {
  3183. *to = *from;
  3184. from = (PIA32FPBYTES) (((UINT_PTR) from) + 16);
  3185. to = (PIA32FPBYTES) (((UINT_PTR) to) + 10);
  3186. }
  3187. }
  3188. VOID
  3189. Wow64CopyFpToIa64Byte16(
  3190. IN PVOID Byte10Fp,
  3191. IN OUT PVOID Byte16Fp,
  3192. IN ULONG NumRegs)
  3193. {
  3194. ULONG i;
  3195. PIA32FPBYTES from, to; // UNALIGNED
  3196. from = (PIA32FPBYTES) Byte10Fp;
  3197. to = (PIA32FPBYTES) Byte16Fp;
  3198. for (i = 0; i < NumRegs; i++) {
  3199. *to = *from;
  3200. from = (PIA32FPBYTES) (((UINT_PTR) from) + 10);
  3201. to = (PIA32FPBYTES) (((UINT_PTR) to) + 16);
  3202. }
  3203. }
  3204. //
  3205. // Alas, nothing is easy. The ia32 xmmi instructions use 16 bytes and pack
  3206. // them as nice 16 byte structs. Unfortunately, ia64 handles it as 2 8-byte
  3207. // values (using just the mantissa part). So, another conversion is required
  3208. //
  3209. VOID
  3210. Wow64CopyXMMIToIa64Byte16(
  3211. IN PVOID ByteXMMI,
  3212. IN OUT PVOID Byte16Fp,
  3213. IN ULONG NumRegs)
  3214. {
  3215. ULONG i;
  3216. UNALIGNED ULONGLONG *from;
  3217. ULONGLONG *to;
  3218. from = (PULONGLONG) ByteXMMI;
  3219. to = (PULONGLONG) Byte16Fp;
  3220. //
  3221. // although we have NumRegs xmmi registers, each register is 16 bytes
  3222. // wide. This code does things in 8-byte chunks, so total
  3223. // number of times to do things is 2 * NumRegs...
  3224. //
  3225. NumRegs *= 2;
  3226. for (i = 0; i < NumRegs; i++) {
  3227. *to++ = *from++; // Copy over the mantissa part
  3228. *to++ = 0x1003e; // Force the exponent part
  3229. // (see ia64 eas, ia32 FP section - 6.2.7
  3230. // for where this magic number comes from)
  3231. }
  3232. }
  3233. VOID
  3234. Wow64CopyXMMIFromIa64Byte16(
  3235. IN PVOID Byte16Fp,
  3236. IN OUT PVOID ByteXMMI,
  3237. IN ULONG NumRegs)
  3238. {
  3239. ULONG i;
  3240. ULONGLONG *from;
  3241. UNALIGNED ULONGLONG *to;
  3242. from = (PULONGLONG) Byte16Fp;
  3243. to = (PULONGLONG) ByteXMMI;
  3244. //
  3245. // although we have NumRegs xmmi registers, each register is 16 bytes
  3246. // wide. This code does things in 8-byte chunks, so total
  3247. // number of times to do things is 2 * NumRegs...
  3248. //
  3249. NumRegs *= 2;
  3250. for (i = 0; i < NumRegs; i++) {
  3251. *to++ = *from++; // Copy over the mantissa part
  3252. from++; // Skip over the exponent part
  3253. }
  3254. }
  3255. VOID
  3256. Wow64RotateFpTop(
  3257. IN ULONGLONG Ia64_FSR,
  3258. IN OUT FLOAT128 UNALIGNED *ia32FxSave)
  3259. /*++
  3260. Routine Description:
  3261. On transition from ia64 mode to ia32 (and back), the f8-f15 registers
  3262. contain the st[0] to st[7] fp stack values. Alas, these values don't
  3263. map one-one, so the FSR.top bits are used to determine which ia64
  3264. register has the top of stack. We then need to rotate these registers
  3265. since ia32 context is expecting st[0] to be the first fp register (as
  3266. if FSR.top is zero). This routine only works on full 16-byte ia32
  3267. saved fp data (such as from ExtendedRegisters - the FXSAVE format).
  3268. Other routines can convert this into the older FNSAVE format.
  3269. Arguments:
  3270. Ia64_FSR - The ia64 FSR register. Has the FSR.top needed for this routine
  3271. ia32FxSave - The ia32 fp stack (in FXSAVE format). Each ia32 fp register
  3272. uses 16 bytes.
  3273. Return Value:
  3274. None.
  3275. --*/
  3276. {
  3277. ULONG top = (ULONG) ((Ia64_FSR >> 11) & 0x7);
  3278. if (top) {
  3279. FLOAT128 tmpFloat[NUMBER_OF_387REGS];
  3280. ULONG i;
  3281. for (i = 0; i < NUMBER_OF_387REGS; i++) {
  3282. tmpFloat[i] = ia32FxSave[i];
  3283. }
  3284. for (i = 0; i < NUMBER_OF_387REGS; i++) {
  3285. ia32FxSave[i] = tmpFloat[(i + top) % NUMBER_OF_387REGS];
  3286. }
  3287. }
  3288. }
  3289. //
  3290. // And now for the final yuck... The ia64 context for floating point
  3291. // is saved/loaded using spill/fill instructions. This format is different
  3292. // than the 10-byte fp format so we need a conversion routine from spill/fill
  3293. // to/from 10byte fp
  3294. //
  3295. VOID
  3296. Wow64CopyIa64FromSpill(
  3297. IN PFLOAT128 SpillArea,
  3298. IN OUT FLOAT128 UNALIGNED *ia64Fp,
  3299. IN ULONG NumRegs)
  3300. /*++
  3301. Routine Description:
  3302. This function copies fp values from the ia64 spill/fill format
  3303. into the ia64 80-bit format. The exponent needs to be adjusted
  3304. according to the EAS (5-12) regarding Memory to Floating Point
  3305. Register Data Translation in the ia64 floating point chapter
  3306. Arguments:
  3307. SpillArea - The ia64 area that has the spill format for fp
  3308. ia64Fp - The location which will get the ia64 fp in 80-bit
  3309. double-extended format
  3310. NumRegs - Number of registers to convert
  3311. Return Value:
  3312. None.
  3313. --*/
  3314. {
  3315. ULONG i;
  3316. for (i = 0; i < NumRegs; i++) {
  3317. ULONG64 Sign = ((SpillArea->HighPart & (1i64 << 17)) != 0);
  3318. ULONG64 Significand = SpillArea->LowPart;
  3319. ULONG64 Exponent = SpillArea->HighPart & 0x1ffff;
  3320. if (Exponent && Significand)
  3321. {
  3322. if (Exponent == 0x1ffff) // NaNs and Infinities
  3323. {
  3324. Exponent = 0x7fff;
  3325. }
  3326. else
  3327. {
  3328. ULONG64 Rebias = 0xffff - 0x3fff;
  3329. Exponent -= Rebias;
  3330. }
  3331. }
  3332. ia64Fp->HighPart = (Sign << 15) | Exponent;
  3333. ia64Fp->LowPart = Significand;
  3334. ia64Fp++;
  3335. SpillArea++;
  3336. }
  3337. }
  3338. VOID
  3339. Wow64CopyIa64ToFill(
  3340. IN FLOAT128 UNALIGNED *ia64Fp,
  3341. IN OUT PFLOAT128 FillArea,
  3342. IN ULONG NumRegs)
  3343. /*++
  3344. Routine Description:
  3345. This function copies fp values from the ia64 80-bit format
  3346. into the fill/spill format used by the os for save/restore
  3347. of the ia64 context. The only magic here is putting back some
  3348. values that get truncated when converting from spill/fill to
  3349. 80-bits. The exponent needs to be adjusted according to the
  3350. EAS (5-12) regarding Memory to Floating Point Register Data
  3351. Translation in the ia64 floating point chapter
  3352. Arguments:
  3353. ia64Fp - The ia64 fp in 80-bit double-extended format
  3354. FillArea - The ia64 area that will get the fill format for fp
  3355. for the copy into the ia64 context area
  3356. NumRegs - Number of registers to convert
  3357. Return Value:
  3358. None.
  3359. --*/
  3360. {
  3361. ULONG i;
  3362. for (i = 0; i < NumRegs; i++) {
  3363. ULONG64 Sign = ((ia64Fp->HighPart & (1i64 << 15)) != 0);
  3364. ULONG64 Significand = ia64Fp->LowPart;
  3365. ULONG64 Exponent = ia64Fp->HighPart & 0x7fff;
  3366. if (Exponent && Significand)
  3367. {
  3368. if (Exponent == 0x7fff) // Infinity
  3369. {
  3370. Exponent = 0x1ffff;
  3371. }
  3372. else
  3373. {
  3374. ULONGLONG Rebias = 0xffff-0x3fff;
  3375. Exponent += Rebias;
  3376. }
  3377. }
  3378. FillArea->LowPart = Significand;
  3379. FillArea->HighPart = (Sign << 17) | Exponent;
  3380. ia64Fp++;
  3381. FillArea++;
  3382. }
  3383. }
  3384. ULONG
  3385. MapDbgSlotIa64ToX86_GetSize(ULONG64 Db1, BOOL* Valid)
  3386. {
  3387. ULONG64 Size = (~Db1 & IA64_DBG_MASK_MASK);
  3388. if (Size > 3)
  3389. {
  3390. *Valid = FALSE;
  3391. }
  3392. return (ULONG)Size;
  3393. }
  3394. void
  3395. MapDbgSlotIa64ToX86_InvalidateAddr(ULONG64 Db, BOOL* Valid)
  3396. {
  3397. if (Db != (ULONG64)(ULONG)Db)
  3398. {
  3399. *Valid = FALSE;
  3400. }
  3401. }
  3402. ULONG
  3403. MapDbgSlotIa64ToX86_ExecTypeSize(
  3404. UINT Slot,
  3405. ULONG64 Db,
  3406. ULONG64 Db1,
  3407. BOOL* Valid)
  3408. {
  3409. ULONG TypeSize;
  3410. if (!(Db1 >> 63))
  3411. {
  3412. *Valid = FALSE;
  3413. }
  3414. TypeSize = (MapDbgSlotIa64ToX86_GetSize(Db1, Valid) << 2);
  3415. MapDbgSlotIa64ToX86_InvalidateAddr(Db, Valid);
  3416. return TypeSize;
  3417. }
  3418. ULONG
  3419. MapDbgSlotIa64ToX86_DataTypeSize(
  3420. UINT Slot,
  3421. ULONG64 Db,
  3422. ULONG64 Db1,
  3423. BOOL* Valid)
  3424. {
  3425. ULONG TypeSize = (ULONG)(Db1 >> 62);
  3426. if ((TypeSize != 1) && (TypeSize != 3))
  3427. {
  3428. *Valid = FALSE;
  3429. }
  3430. TypeSize |= (MapDbgSlotIa64ToX86_GetSize(Db1, Valid) << 2);
  3431. MapDbgSlotIa64ToX86_InvalidateAddr(Db, Valid);
  3432. return TypeSize;
  3433. }
  3434. BOOL
  3435. MapDbgSlotIa64ToX86(
  3436. UINT Slot,
  3437. ULONG64 Ipsr,
  3438. ULONG64 DbD,
  3439. ULONG64 DbD1,
  3440. ULONG64 DbI,
  3441. ULONG64 DbI1,
  3442. ULONG* Dr7,
  3443. ULONG* Dr)
  3444. {
  3445. BOOL DataValid = TRUE, ExecValid = TRUE, Valid = TRUE;
  3446. ULONG DataTypeSize, ExecTypeSize;
  3447. // XXX olegk - remove this after IA64_REG_MAX_DATA_BREAKPOINTS will be changed to 4
  3448. if (Slot >= IA64_REG_MAX_DATA_BREAKPOINTS)
  3449. {
  3450. return TRUE;
  3451. }
  3452. DataTypeSize = MapDbgSlotIa64ToX86_DataTypeSize(Slot, DbD, DbD1, &DataValid);
  3453. ExecTypeSize = MapDbgSlotIa64ToX86_ExecTypeSize(Slot, DbI, DbI1, &ExecValid);
  3454. if (DataValid)
  3455. {
  3456. if (!ExecValid)
  3457. {
  3458. *Dr = (ULONG)DbD;
  3459. *Dr7 |= (X86_DR7_LOCAL_EXACT_ENABLE |
  3460. (1 << Slot * 2) |
  3461. (DataTypeSize << (16 + Slot * 4)));
  3462. return !DbI && !DbI1;
  3463. }
  3464. }
  3465. else if (ExecValid)
  3466. {
  3467. *Dr = (ULONG)DbI;
  3468. *Dr7 |= (X86_DR7_LOCAL_EXACT_ENABLE |
  3469. (1 << Slot * 2) |
  3470. (ExecTypeSize << (16 + Slot * 4)));
  3471. return !DbD && !DbD1;
  3472. }
  3473. *Dr7 &= ~(X86_DR7_LOCAL_EXACT_ENABLE |
  3474. (0xf << (16 + Slot * 4)) |
  3475. (1 << Slot * 2));
  3476. if (!DbD && !DbD1 && !DbI && !DbI1)
  3477. {
  3478. *Dr = 0;
  3479. return TRUE;
  3480. }
  3481. *Dr = ~(ULONG)0;
  3482. return FALSE;
  3483. }
  3484. void
  3485. MapDbgSlotX86ToIa64(
  3486. UINT Slot,
  3487. ULONG Dr7,
  3488. ULONG Dr,
  3489. ULONG64* Ipsr,
  3490. ULONG64* DbD,
  3491. ULONG64* DbD1,
  3492. ULONG64* DbI,
  3493. ULONG64* DbI1)
  3494. {
  3495. UINT TypeSize;
  3496. ULONG64 Control;
  3497. if (!(Dr7 & (1 << Slot * 2)))
  3498. {
  3499. return;
  3500. }
  3501. if (Dr == ~(ULONG)0)
  3502. {
  3503. return;
  3504. }
  3505. TypeSize = Dr7 >> (16 + Slot * 4);
  3506. Control = (IA64_DBG_REG_PLM_USER | IA64_DBG_MASK_MASK) &
  3507. ~(ULONG64)(TypeSize >> 2);
  3508. switch (TypeSize & 0x3)
  3509. {
  3510. case 0x0: // Exec
  3511. *DbI1 = Control | IA64_DBR_EXEC;
  3512. *DbI = Dr;
  3513. break;
  3514. case 0x1: // Write
  3515. *DbD1 = Control | IA64_DBR_WR;
  3516. *DbD = Dr;
  3517. break;
  3518. case 0x3: // Read/Write
  3519. *DbD1 = Control | IA64_DBR_RD | IA64_DBR_WR;
  3520. *DbD = Dr;
  3521. break;
  3522. default:
  3523. return;
  3524. }
  3525. *Ipsr |= (1i64 << PSR_DB);
  3526. }