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.

582 lines
12 KiB

  1. //++
  2. //
  3. // Module name
  4. // miscs.s
  5. // Author
  6. // Allen Kay ([email protected]) Jun-12-95
  7. // Description
  8. // Misc. assembly functions.
  9. //
  10. //---
  11. #include "ksia64.h"
  12. .file "miscs.s"
  13. .global PalProcPhysical
  14. .global PalPhysicalBase
  15. .global PalTrPs
  16. .global IoPortPhysicalBase
  17. .global IoPortTrPs
  18. .global BdPcr
  19. //
  20. // Setup CPU state to go from physical to virtual
  21. //
  22. LEAF_ENTRY(MempGoVirtual)
  23. rpT0 = t21
  24. rpT1 = t20
  25. rTrPs = t19
  26. rPPN = t18
  27. rPsr = t17
  28. mov ar.rsc = r0
  29. mov rPsr = psr
  30. ;;
  31. rsm (1 << PSR_I)
  32. ;;
  33. rsm (1 << PSR_IC)
  34. ;;
  35. srlz.i
  36. ;;
  37. movl t0 = FPSR_FOR_KERNEL
  38. ;;
  39. mov ar.fpsr = t0 // initialize fpsr
  40. ;;
  41. //
  42. // Initialize Region Registers
  43. //
  44. mov t1 = (START_GLOBAL_RID << RR_RID) | (PAGE_SHIFT << RR_PS) | RR_PS_VE
  45. movl t3 = KSEG0_BASE
  46. ;;
  47. mov rr[t3] = t1
  48. //
  49. // Invalidate all protection key registers
  50. //
  51. mov t1 = zero
  52. ;;
  53. Bl_PKRLoop:
  54. mov pkr[t1] = zero
  55. ;;
  56. add t1 = 1, t1
  57. add t2 = 1, t2
  58. ;;
  59. cmp.gtu pt0, pt1 = PKRNUM - 1, t1
  60. ;;
  61. (pt0) br.cond.sptk.few.clr Bl_PKRLoop
  62. ;;
  63. #if 0
  64. //
  65. // Setup the 1-to-1 translation for the loader
  66. //
  67. movl t0 = BL_16M
  68. ;;
  69. movl t2 = ITIR_VALUE(0,PS_16M)
  70. mov cr.ifa = t0
  71. ;;
  72. mov cr.itir = t2
  73. ;;
  74. mov t3 = BL_LOADER_INDEX
  75. movl t2 = TR_VALUE(1,BL_16M,3,0,1,1,0,1)
  76. ;;
  77. itr.d dtr[t3] = t2
  78. ;;
  79. itr.i itr[t3] = t2
  80. #endif
  81. //
  82. //
  83. // Setup the first 16MB translation for the drivers.
  84. //
  85. movl t0 = KSEG0_BASE + BL_16M
  86. ;;
  87. movl t2 = ITIR_VALUE(0,PS_16M)
  88. mov cr.ifa = t0
  89. ;;
  90. mov cr.itir = t2
  91. ;;
  92. mov t3 = DTR_DRIVER0_INDEX
  93. movl t2 = TR_VALUE(1,BL_16M,3,0,1,1,0,1)
  94. ;;
  95. itr.d dtr[t3] = t2
  96. ;;
  97. itr.i itr[t3] = t2
  98. //
  99. // Setup the second 16MB translation for the drivers.
  100. //
  101. movl t0 = KSEG0_BASE + BL_32M;
  102. ;;
  103. movl t2 = ITIR_VALUE(0,PS_16M)
  104. mov cr.ifa = t0
  105. ;;
  106. mov cr.itir = t2
  107. ;;
  108. mov t3 = DTR_DRIVER1_INDEX
  109. movl t2 = TR_VALUE(1,BL_32M,3,0,1,1,0,1)
  110. ;;
  111. itr.d dtr[t3] = t2
  112. ;;
  113. itr.i itr[t3] = t2
  114. //
  115. // Setup 16MB translation for kernel/hal binary.
  116. //
  117. movl t0 = KSEG0_BASE + BL_48M;
  118. ;;
  119. movl t2 = ITIR_VALUE(0,PS_16M)
  120. mov cr.ifa = t0
  121. ;;
  122. mov cr.itir = t2
  123. ;;
  124. mov t3 = DTR_KERNEL_INDEX
  125. movl t2 = TR_VALUE(1,BL_48M,3,0,1,1,0,1)
  126. ;;
  127. itr.d dtr[t3] = t2
  128. ;;
  129. itr.i itr[t3] = t2
  130. //
  131. // Setup 16MB translation for decompression buffer used by setupldr.
  132. //
  133. movl t0 = KSEG0_BASE + BL_64M;
  134. ;;
  135. movl t2 = ITIR_VALUE(0,PS_16M)
  136. mov cr.ifa = t0
  137. ;;
  138. mov cr.itir = t2
  139. ;;
  140. mov t3 = BL_DECOMPRESS_INDEX
  141. movl t2 = TR_VALUE(1,BL_64M,3,0,1,1,0,1)
  142. ;;
  143. itr.d dtr[t3] = t2
  144. ;;
  145. itr.i itr[t3] = t2
  146. //
  147. //
  148. // Setup translation for PAL.
  149. //
  150. movl rpT0 = PalPhysicalBase // PAL base addr
  151. movl rpT1 = PalTrPs // PAL page size
  152. movl t1 = VIRTUAL_PAL_BASE
  153. ;;
  154. ld8 t0 = [rpT0]
  155. ld8 rTrPs = [rpT1]
  156. mov cr.ifa = t1
  157. movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
  158. movl t5 = TR_VALUE(1,0,3,0,1,1,0,1)
  159. ;;
  160. shl t2 = rTrPs, ITIR_PS
  161. and t6 = t0, t4 // t6 is PPN in GR[r]
  162. ;;
  163. mov cr.itir = t2
  164. ;;
  165. mov t3 = DTR_HAL_INDEX // pre-assigned index
  166. or t2 = t5, t6 // t2 is now GR[r]
  167. ;;
  168. itr.d dtr[t3] = t2
  169. //
  170. // Setup translation for I/O port space
  171. //
  172. movl rpT0 = IoPortPhysicalBase // IO Port base addr
  173. movl rpT1 = IoPortTrPs // IO Port page size
  174. movl t1 = VIRTUAL_IO_BASE
  175. ;;
  176. ld8 t0 = [rpT0]
  177. ld8 rTrPs = [rpT1]
  178. mov cr.ifa = t1
  179. movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
  180. movl t5 = TR_VALUE(1,0,3,0,1,1,4,1)
  181. ;;
  182. shl t2 = rTrPs, ITIR_PS
  183. and t6 = t0, t4 // t6 is PPN in GR[r]
  184. ;;
  185. mov cr.itir = t2
  186. ;;
  187. mov t3 = DTR_IO_PORT_INDEX // pre-assigned index
  188. or t2 = t5, t6 // t2 is now GR[r]
  189. ;;
  190. itr.d dtr[t3] = t2
  191. //
  192. // Setup translation for BdPcr
  193. //
  194. movl t0 = BdPcr
  195. movl rTrPs = PS_4M
  196. ;;
  197. mov cr.ifa = t0
  198. movl t4 = IITR_ATTRIBUTE_PPN_MASK // construct GR[r]
  199. movl t5 = TR_VALUE(1,0,3,0,1,1,0,1)
  200. ;;
  201. shl t2 = rTrPs, ITIR_PS
  202. and t6 = t0, t4 // t6 is PPN in GR[r]
  203. ;;
  204. mov cr.itir = t2
  205. ;;
  206. mov t3 = DTR_KIPCR_INDEX
  207. or t2 = t5, t6 // t2 is now GR[r]
  208. ;;
  209. itr.d dtr[t3] = t2
  210. //
  211. // Turn on address translation, interrupt, psr.ed, protection key.
  212. //
  213. movl t1 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_IC,1) | MASK_IA64(PSR_AC,1) | MASK_IA64(PSR_DB,1)
  214. ;;
  215. or t1 = t1, rPsr
  216. ;;
  217. mov cr.ipsr = t1
  218. //
  219. // Initialize DCR to defer all speculation faults
  220. //
  221. mov t0 = DCR_DEFER_ALL
  222. ;;
  223. mov cr.dcr = t0
  224. //
  225. // Prepare to do RFI to return to the caller.
  226. //
  227. movl t0 = return_label
  228. ;;
  229. mov cr.iip = t0
  230. ;;
  231. mov cr.ifs = r0
  232. ;;
  233. rfi
  234. ;;
  235. return_label:
  236. mov v0 = zero
  237. ;;
  238. LEAF_RETURN
  239. LEAF_EXIT(MempGoVirtual)
  240. //
  241. // Flip psr.it bit from virtual to physical addressing mode.
  242. //
  243. LEAF_ENTRY(FlipToPhysical)
  244. rPsr = t17
  245. rsm (1 << PSR_I)
  246. ;;
  247. rsm (1 << PSR_IC)
  248. ;;
  249. srlz.i
  250. ;;
  251. mov rPsr = psr
  252. movl t1 = MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1)
  253. movl t2 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IC,1)
  254. ;;
  255. xor t1 = t1, rPsr
  256. ;;
  257. or t1 = t1, t2
  258. ;;
  259. mov cr.ipsr = t1
  260. //
  261. // Prepare to do RFI to return to the caller.
  262. //
  263. movl t0 = FlipToPhysicalReturn
  264. ;;
  265. mov cr.iip = t0
  266. ;;
  267. mov cr.ifs = r0
  268. ;;
  269. rfi
  270. ;;
  271. FlipToPhysicalReturn:
  272. mov v0 = zero
  273. ;;
  274. LEAF_RETURN
  275. LEAF_EXIT(FlipToPhysical)
  276. //
  277. // Flip psr.it bit from physical to virtual addressing mode.
  278. //
  279. LEAF_ENTRY(FlipToVirtual)
  280. rPsr = t17
  281. rsm (1 << PSR_I)
  282. ;;
  283. rsm (1 << PSR_IC)
  284. ;;
  285. srlz.i
  286. ;;
  287. mov rPsr = psr
  288. movl t1 = MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IC,1)
  289. ;;
  290. or t1 = t1, rPsr
  291. ;;
  292. mov cr.ipsr = t1
  293. //
  294. // Prepare to do RFI to return to the caller.
  295. //
  296. movl t0 = FlipToVirtualReturn
  297. ;;
  298. mov cr.iip = t0
  299. ;;
  300. mov cr.ifs = r0
  301. ;;
  302. rfi
  303. ;;
  304. FlipToVirtualReturn:
  305. mov v0 = zero
  306. ;;
  307. LEAF_RETURN
  308. LEAF_EXIT(FlipToVirtual)
  309. //
  310. // Clean up TR mappings used only by NT loader.
  311. //
  312. LEAF_ENTRY(BlTrCleanUp)
  313. rpT0 = t22
  314. rPsr = t17
  315. //
  316. // purge BL_DECOMPRESS_INDEX
  317. //
  318. movl t0 = PS_16M << PS_SHIFT
  319. movl t1 = KSEG0_BASE + BL_64M
  320. ;;
  321. ptr.d t1, t0
  322. ;;
  323. #if 0
  324. //
  325. // purge BL_LOADER_INDEX
  326. //
  327. movl t0 = PS_16M << PS_SHIFT
  328. movl t1 = BL_16M
  329. ;;
  330. ptr.i t1, t0
  331. ;;
  332. ptr.d t1, t0
  333. #endif
  334. //
  335. // purge BdPcr translation.
  336. //
  337. movl t0 = BdPcr
  338. movl t1 = PS_4M << PS_SHIFT
  339. ;;
  340. ptr.d t0, t1
  341. ;;
  342. //
  343. // Turn on address translation, interrupt, psr.ed, protection key.
  344. //
  345. rsm (1 << PSR_I)
  346. ;;
  347. rsm (1 << PSR_IC)
  348. ;;
  349. srlz.i
  350. ;;
  351. //
  352. // At this point, turn on psr.it so that we can pass control to
  353. // the kernel.
  354. //
  355. mov rPsr = psr
  356. movl t1 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IT,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_IC,1) | MASK_IA64(PSR_AC,1) | MASK_IA64(PSR_DB,1)
  357. ;;
  358. or t1 = t1, rPsr
  359. ;;
  360. mov cr.ipsr = t1
  361. //
  362. // Prepare to do RFI to return to the caller.
  363. //
  364. movl t0 = BlTrCleanupReturn
  365. ;;
  366. mov cr.iip = t0
  367. ;;
  368. mov cr.ifs = r0
  369. ;;
  370. rfi
  371. ;;
  372. BlTrCleanupReturn:
  373. mov v0 = zero
  374. ;;
  375. LEAF_RETURN
  376. LEAF_EXIT (BlTrCleanUp)
  377. //++
  378. //
  379. // VOID
  380. // BlpPalProc(
  381. // LONGLONG a0, /* PAL function ID */
  382. // LONGLONG a1, /* PAL argument */
  383. // LONGLONG a2, /* PAL argument */
  384. // LONGLONG a3 /* PAL argument */
  385. // );
  386. //
  387. // Routine Description
  388. // This routine sets up the correct registers for input into PAL depending on
  389. // if the call uses static or stacked registers, turns off interrupts, ensures
  390. // the correct bank registers are being used and calls into the PAL.
  391. //
  392. // Return Values:
  393. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  394. //--
  395. NESTED_ENTRY(BlpPalProc)
  396. NESTED_SETUP(4,3,4,0)
  397. PROLOGUE_END
  398. // For both the static and stacked register conventions, load r28 with FunctionID
  399. mov r28 = a0
  400. // If static register calling convention (1-255, 512-767), copy arguments to r29->r31
  401. // Otherwise, copy to out0->out3 so they are in r32->r35 in PAL_PROC
  402. mov t0 = a0
  403. ;;
  404. shr t0 = t0, 8
  405. ;;
  406. tbit.z pt0, pt1 = t0, 0
  407. ;;
  408. //
  409. // Static proc: do br not call
  410. //
  411. (pt0) mov r29 = a1
  412. (pt0) mov r30 = a2
  413. (pt0) mov r31 = a3
  414. //
  415. // Stacked call
  416. //
  417. (pt1) mov out0 = a0
  418. (pt1) mov out1 = a1
  419. (pt1) mov out2 = a2
  420. (pt1) mov out3 = a3
  421. // Load up the address of PAL_PROC and call it
  422. addl t1 = @gprel(PalProcPhysical), gp
  423. ;;
  424. ld8 t0 = [t1]
  425. ;;
  426. mov bt0 = t0
  427. // Call into PAL_PROC
  428. (pt0) addl t1 = @ltoff(PalReturn), gp
  429. ;;
  430. (pt0) ld8 t0 = [t1]
  431. ;;
  432. (pt0) mov brp = t0
  433. ;;
  434. // Disable interrupts
  435. DISABLE_INTERRUPTS(loc2)
  436. ;;
  437. srlz.d
  438. ;;
  439. (pt0) br.sptk.many bt0
  440. ;;
  441. (pt1) br.call.sptk brp = bt0
  442. ;;
  443. PalReturn:
  444. // Restore the interrupt state
  445. RESTORE_INTERRUPTS(loc2)
  446. ;;
  447. NESTED_RETURN
  448. NESTED_EXIT(BlpPalProc)