Leaked source code of windows server 2003
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.

700 lines
17 KiB

  1. //++
  2. //
  3. // Module Name:
  4. //
  5. // thunk.s
  6. //
  7. // Abstract:
  8. //
  9. // This module implements all Win32 thunks. This includes the
  10. /// first level thread starter...
  11. //
  12. // Author:
  13. //
  14. // 12-Oct-1995
  15. //
  16. // Revision History:
  17. //
  18. //--
  19. #include "ksia64.h"
  20. .file "thunk.s"
  21. //++
  22. //
  23. // VOID
  24. // BaseThreadStartThunk(
  25. // IN PTHREAD_START_ROUTINE StartRoutine,
  26. // IN PVOID ThreadParameter
  27. // )
  28. //
  29. // Routine Description:
  30. //
  31. // This function calls to the portable thread starter after moving
  32. // its arguments from registers to the argument registers.
  33. //
  34. // Arguments:
  35. //
  36. // s1 - StartRoutine
  37. // s2 - ThreadParameter
  38. //
  39. // Return Value:
  40. //
  41. // Never Returns
  42. //
  43. //--
  44. PublicFunction(BaseThreadStart)
  45. LEAF_ENTRY(BaseThreadStartThunk)
  46. LEAF_SETUP(0,0,2,0)
  47. mov out0=s1
  48. mov out1=s2
  49. br.many BaseThreadStart
  50. ;;
  51. //
  52. // never come back here
  53. //
  54. LEAF_EXIT(BaseThreadStartThunk)
  55. //++
  56. //
  57. // VOID
  58. // BaseProcessStartThunk(
  59. // IN PTHREAD_START_ROUTINE StartRoutine,
  60. // IN PVOID ThreadParameter
  61. // )
  62. //
  63. // Routine Description:
  64. //
  65. // This function calls to the portable thread starter after moving
  66. // its arguments from registers to the argument registers.
  67. //
  68. // Arguments:
  69. //
  70. // s1 - StartRoutine
  71. // s2 - ThreadParameter
  72. //
  73. // Return Value:
  74. //
  75. // Never Returns
  76. //
  77. //--
  78. PublicFunction(BaseProcessStart)
  79. LEAF_ENTRY(BaseProcessStartThunk)
  80. alloc t22 = ar.pfs, 0, 0, 1, 0
  81. mov out0=s1
  82. br BaseProcessStart // jump process wrapper.
  83. ;;
  84. LEAF_EXIT(BaseProcessStartThunk)
  85. //++
  86. //
  87. // VOID
  88. // SwitchToFiber(
  89. // PFIBER NewFiber
  90. // )
  91. //
  92. // Routine Description:
  93. //
  94. // This function saves the state of the current fiber and switches
  95. // to the new fiber.
  96. //
  97. // Arguments:
  98. //
  99. // NewFiber (a0) - Supplies the address of the new fiber.
  100. //
  101. // Return Value:
  102. //
  103. // None
  104. //
  105. //--
  106. LEAF_ENTRY(SwitchToFiber)
  107. // local register aliases
  108. rOldFb = t21
  109. rOldCx = t20
  110. rNewFb = t19
  111. rNewCx = t18
  112. rA0 = t17
  113. dest1 = t10
  114. dest2 = t11
  115. dest4 = t12
  116. dest5 = t13
  117. //
  118. // set up pointers to old and new fiber and context records
  119. //
  120. add rNewFb = zero, a0
  121. add rNewCx = FbFiberContext, a0
  122. add t0 = TeFiberData, teb
  123. ;;
  124. ld8 t1 = [t0]
  125. mov rA0 = a0
  126. ;;
  127. add rOldFb = 0, t1
  128. add rOldCx = FbFiberContext, t1
  129. ;;
  130. //
  131. // step 1
  132. // save current state in to old fiber's fiber and context rec
  133. //
  134. //
  135. // save fiber exception list and stack info
  136. //
  137. flushrs
  138. add dest1 = TeExceptionList, teb // TEB
  139. add dest2 = FbExceptionList, rOldFb // Old fiber
  140. //
  141. // also save RSE stack info
  142. //
  143. add dest4 = TeBStoreLimit, teb
  144. add dest5 = FbBStoreLimit, rOldFb
  145. ;;
  146. ld8 t0 = [dest1], TeStackLimit - TeExceptionList
  147. ld8 t1 = [dest4], TeFlsData - TeBStoreLimit
  148. ;;
  149. st8 [dest2] = t0, FbStackLimit - FbExceptionList
  150. st8 [dest5] = t1, FbFlsData - FbBStoreLimit
  151. ;;
  152. ld8 t0 = [dest1]
  153. ld8 t1 = [dest4]
  154. ;;
  155. st8 [dest2] = t0
  156. st8 [dest5] = t1
  157. //
  158. // spill low non-volatile fp registers 0-3, 5-19
  159. //
  160. add dest1 = CxFltS0, rOldCx
  161. add dest2 = CxFltS1, rOldCx
  162. ;;
  163. mov t2 = ar.fpsr //FPSR
  164. mov t3 = ar28 //FSR
  165. mov t4 = ar29 //FIR
  166. mov t5 = ar30 //FDR
  167. stf.spill [dest1] = fs0, CxFltS2 - CxFltS0
  168. stf.spill [dest2] = fs1, CxFltS3 - CxFltS1
  169. ;;
  170. stf.spill [dest1] = fs2, CxFltS4 - CxFltS2
  171. stf.spill [dest2] = fs3, CxFltS5 - CxFltS3
  172. ;;
  173. stf.spill [dest1] = fs4, CxFltS6 - CxFltS4
  174. stf.spill [dest2] = fs5, CxFltS7 - CxFltS5
  175. ;;
  176. stf.spill [dest1] = fs6, CxFltS8 - CxFltS6
  177. stf.spill [dest2] = fs7, CxFltS9 - CxFltS7
  178. ;;
  179. stf.spill [dest1] = fs8, CxFltS10 - CxFltS8
  180. stf.spill [dest2] = fs9, CxFltS11 - CxFltS9
  181. ;;
  182. stf.spill [dest1] = fs10, CxFltS12 - CxFltS10
  183. stf.spill [dest2] = fs11, CxFltS13 - CxFltS11
  184. ;;
  185. stf.spill [dest1] = fs12, CxFltS14 - CxFltS12
  186. stf.spill [dest2] = fs13, CxFltS15 - CxFltS13
  187. ;;
  188. stf.spill [dest1] = fs14, CxFltS16 - CxFltS14
  189. stf.spill [dest2] = fs15, CxFltS17 - CxFltS15
  190. ;;
  191. stf.spill [dest1] = fs16, CxFltS18 - CxFltS16
  192. stf.spill [dest2] = fs17, CxFltS19 - CxFltS17
  193. ;;
  194. stf.spill [dest1] = fs18
  195. stf.spill [dest2] = fs19
  196. //
  197. // fp status registers
  198. //
  199. add dest1 = CxStFPSR, rOldCx
  200. add dest2 = CxStFSR, rOldCx
  201. ;;
  202. st8 [dest1] = t2
  203. ;;
  204. st8 [dest2] = t3, CxStFDR - CxStFSR
  205. add dest1 = CxStFIR, rOldCx
  206. ;;
  207. st8 [dest1] = t4
  208. ;;
  209. st8 [dest2] = t5
  210. //
  211. // save old unat before starting the spills
  212. //
  213. mov t6 = ar.unat
  214. add dest4 = CxApUNAT, rOldCx
  215. ;;
  216. st8 [dest4] = t6
  217. mov ar.unat = zero
  218. ;;
  219. // ordering ? should not start spilling before unat is saved
  220. // save sp and preserved int registers
  221. add dest4 = CxIntS0, rOldCx
  222. add dest5 = CxIntSp, rOldCx
  223. ;;
  224. .mem.offset 0,0
  225. st8.spill [dest5] = sp, CxIntS1 - CxIntSp
  226. .mem.offset 8,0
  227. st8.spill [dest4] = s0, CxIntS2 - CxIntS0
  228. ;;
  229. .mem.offset 0,0
  230. st8.spill [dest5] = s1, CxIntS3 - CxIntS1
  231. .mem.offset 8,0
  232. st8.spill [dest4] = s2
  233. ;;
  234. st8.spill [dest5] = s3
  235. // save predicates
  236. add dest4 = CxPreds, rOldCx
  237. add dest5 = CxBrRp, rOldCx
  238. mov t7 = pr
  239. ;;
  240. st8 [dest4] = t7, CxBrS0 - CxPreds
  241. // save preserved branch registers
  242. mov t8 = brp
  243. ;;
  244. st8 [dest5] = t8, CxBrS1 - CxBrRp
  245. mov t9 = bs0
  246. ;;
  247. st8 [dest4] = t9, CxBrS2 - CxBrS0
  248. mov t1 = bs1
  249. ;;
  250. st8 [dest5] = t1, CxBrS3 - CxBrS1
  251. mov t2 = bs2
  252. ;;
  253. st8 [dest4] = t2, CxBrS4 - CxBrS2
  254. mov t3 = bs3
  255. ;;
  256. st8 [dest5] = t3
  257. mov t4 = bs4
  258. ;;
  259. st8 [dest4] = t4
  260. // save other applicatin registers
  261. //
  262. mov t6 = ar.lc
  263. add dest4 = CxApLC, rOldCx
  264. add dest5 = CxApEC, rOldCx
  265. ;;
  266. st8 [dest4] = t6, CxRsPFS - CxApLC
  267. mov t7 = ar.ec
  268. ;;
  269. st8 [dest5] = t7, CxRsRSC - CxApEC
  270. //
  271. // save RSE stuff
  272. //
  273. mov t8 = ar.pfs
  274. ;;
  275. st8 [dest4] = t8
  276. mov t9 = ar.rsc
  277. ;;
  278. st8 [dest5] = t9
  279. dep t9 = 0, t9, RSC_MODE, 2 // put in lazy mode
  280. ;;
  281. mov ar.rsc = t9
  282. //
  283. // since we do not use locals, we don't need cover..
  284. // cover
  285. // ;;
  286. ;;
  287. dep t9 = 0, t9, RSC_LOADRS, RSC_LOADRS_LEN // invalidate all
  288. ;;
  289. mov ar.rsc = t9
  290. ;;
  291. loadrs
  292. add dest1 = CxRsRNAT, rOldCx
  293. add dest2 = CxRsBSP, rOldCx
  294. ;;
  295. mov t1 = ar.bsp
  296. ;;
  297. st8 [dest2] = t1
  298. mov t2 = ar.rnat
  299. ;;
  300. st8 [dest1] = t2
  301. // save all spilled NaT bits in in IntNats
  302. add dest1 = CxIntNats, rOldCx
  303. mov t3 = ar.unat
  304. ;;
  305. st8 [dest1] = t3
  306. //
  307. // step 2
  308. // setup the state for new fiber from new context/fiber record
  309. //
  310. // restore exception list and stack info fist
  311. //
  312. add dest1 = TeExceptionList, teb
  313. add dest2 = FbExceptionList, rNewFb
  314. add dest4 = TeBStoreLimit, teb
  315. add dest5 = FbBStoreLimit, rNewFb
  316. ;;
  317. ld8 t0 = [dest2], FbStackBase - FbExceptionList
  318. ld8 t2 = [dest5], FbDeallocationBStore - FbBStoreLimit
  319. ;;
  320. st8 [dest1] = t0, TeStackBase - TeExceptionList
  321. st8 [dest4] = t2, TeDeallocationBStore - TeBStoreLimit
  322. ;;
  323. ld8 t0 = [dest2], FbStackLimit - FbStackBase
  324. ld8 t2 = [dest5], FbFlsData - FbDeallocationBStore
  325. ;;
  326. st8 [dest1] = t0, TeStackLimit - TeStackBase
  327. st8 [dest4] = t2, TeFlsData - TeDeallocationBStore
  328. ;;
  329. ld8 t0 = [dest2]
  330. ld8 t1 = [dest5]
  331. ;;
  332. st8 [dest1] = t0
  333. st8 [dest4] = t1
  334. add dest5 = FbDeallocationStack, rNewFb
  335. add dest4 = TeDeallocationStack, teb
  336. add dest1 = TeFiberData, teb
  337. ;;
  338. ld8 t3 = [dest5]
  339. //
  340. // set the fiber pointer in teb to point to new fiber
  341. //
  342. st8 [dest1] = rA0
  343. add dest2 = CxRsBSP, rNewCx
  344. ;;
  345. st8 [dest4] = t3
  346. ld8 t2 = [dest2], CxRsRNAT - CxRsBSP
  347. add dest1 = CxRsRSC, rNewCx
  348. ;;
  349. ;;
  350. mov ar.bspstore = t2
  351. invala
  352. ld8 t3 = [dest2]
  353. ;;
  354. mov ar.rnat = t3
  355. ld8 t4 = [dest1]
  356. ;;
  357. mov ar.rsc = t4
  358. add dest4 = CxRsPFS, rNewCx
  359. ;;
  360. ld8 t5 = [dest4]
  361. ;;
  362. mov ar.pfs = t5
  363. // restore floating point registers
  364. add dest1 = CxFltS0, rNewCx
  365. add dest2 = CxFltS1, rNewCx
  366. ;;
  367. ldf.fill fs0 = [dest1], CxFltS2 - CxFltS0
  368. ldf.fill fs1 = [dest2] , CxFltS3 - CxFltS1
  369. ;;
  370. ldf.fill fs2 = [dest1], CxFltS4 - CxFltS2
  371. ldf.fill fs3 = [dest2], CxFltS5 - CxFltS3
  372. ;;
  373. ldf.fill fs4 = [dest1], CxFltS6 - CxFltS4
  374. ldf.fill fs5 = [dest2], CxFltS7 - CxFltS5
  375. ;;
  376. ldf.fill fs6 = [dest1], CxFltS8 - CxFltS6
  377. ldf.fill fs7 = [dest2], CxFltS9 - CxFltS7
  378. ;;
  379. ldf.fill fs8 = [dest1], CxFltS10 - CxFltS8
  380. ldf.fill fs9 = [dest2], CxFltS11 - CxFltS9
  381. ;;
  382. ldf.fill fs10 = [dest1], CxFltS12 - CxFltS10
  383. ldf.fill fs11 = [dest2], CxFltS13 - CxFltS11
  384. ;;
  385. ldf.fill fs12 = [dest1], CxFltS14 - CxFltS12
  386. ldf.fill fs13 = [dest2], CxFltS15 - CxFltS13
  387. ;;
  388. ldf.fill fs14 = [dest1], CxFltS16 - CxFltS14
  389. ldf.fill fs15 = [dest2], CxFltS17 - CxFltS15
  390. ;;
  391. ldf.fill fs16 = [dest1], CxFltS18 - CxFltS16
  392. ldf.fill fs17 = [dest2], CxFltS19 - CxFltS17
  393. ;;
  394. ldf.fill fs18 = [dest1]
  395. ldf.fill fs19 = [dest2]
  396. add dest1 = CxStFPSR, rNewCx
  397. add dest2 = CxStFSR, rNewCx
  398. ;;
  399. ld8 t2 = [dest1] //FPSR
  400. ;;
  401. mov ar.fpsr = t2
  402. ld8 t3 = [dest2], CxStFDR - CxStFSR
  403. add dest1 = CxStFIR, rNewCx
  404. ;;
  405. mov ar28 = t3 //FSR
  406. ld8 t4 = [dest1]
  407. ;;
  408. mov ar29 = t4 //FIR
  409. ld8 t5 = [dest2]
  410. ;;
  411. mov ar30 = t5 //FDR
  412. //
  413. // restore ar.unat first, so that fills will restore the
  414. // nat bits correctly
  415. //
  416. add dest4 = CxIntNats, rNewCx
  417. ;;
  418. ld8 t6 = [dest4]
  419. ;;
  420. mov ar.unat = t6
  421. // now start filling the preserved integer registers
  422. //
  423. add dest4 = CxIntS0, rNewCx
  424. add dest5 = CxIntSp, rNewCx
  425. ;;
  426. ld8.fill sp = [dest5], CxIntS1 - CxIntSp
  427. // save preserved integer registers
  428. ld8.fill s0 = [dest4], CxIntS2 - CxIntS0
  429. ;;
  430. ld8.fill s1 = [dest5], CxIntS3 - CxIntS1
  431. ld8.fill s2 = [dest4]
  432. ;;
  433. ld8.fill s3 = [dest5]
  434. // restore predicates and branch registers
  435. add dest4 = CxPreds, rNewCx
  436. add dest5 = CxBrRp, rNewCx
  437. ;;
  438. ld8 t7 = [dest4], CxBrS0 - CxPreds
  439. ;;
  440. mov pr = t7
  441. ld8 t8 = [dest5], CxBrS1 - CxBrRp
  442. ;;
  443. mov brp = t8
  444. ld8 t9 = [dest4], CxBrS2 - CxBrS0
  445. ;;
  446. mov bs0 = t9
  447. ld8 t1 = [dest5], CxBrS3 - CxBrS1
  448. ;;
  449. mov bs1 = t1
  450. ld8 t2 = [dest4], CxBrS4 - CxBrS2
  451. ;;
  452. mov bs2 = t2
  453. ld8 t3 = [dest5]
  454. ;;
  455. mov bs3 = t3
  456. ld8 t4 = [dest4]
  457. ;;
  458. mov bs4 = t4
  459. // restore other applicatin registers
  460. //
  461. add dest4 = CxApLC, rNewCx
  462. add dest5 = CxApEC, rNewCx
  463. ;;
  464. ld8 t6 = [dest4]
  465. ;;
  466. mov ar.lc = t6
  467. ld8 t7 = [dest5]
  468. ;;
  469. mov ar.ec = t7
  470. // finally restore the unat register
  471. //
  472. add dest4 = CxApUNAT, rNewCx
  473. ;;
  474. ld8 t5 = [dest4]
  475. ;;
  476. mov ar.unat = t5
  477. br.ret.sptk brp
  478. //
  479. // this will execute BaseFiberStart if we are switching to
  480. // the new fiber for the first time. otherwise, it will
  481. // return back to new fiber.
  482. //
  483. LEAF_EXIT(SwitchToFiber)
  484. #if 0
  485. LEAF_ENTRY(GenericIACall)
  486. LEAF_SETUP(1,95,0,0)
  487. //
  488. // Load iA state for iVE. Since working with flat 32 in NT,
  489. // much of the state is a constant (per Freds document)
  490. //
  491. mov rBase = teb // Get TEB pointer
  492. // load up selector register constants, we dont care about GS
  493. mov rES = _DataSelector
  494. mov rSS = _DataSelector
  495. mov rDS = _DataSelector
  496. mov rGS = _DataSelector
  497. mov rCS = _CodeSelector
  498. mov rFS = _FsSelector
  499. mov rLDT = _LdtSelector
  500. //
  501. // Setup pointer to iA32 Resources relative to TEB
  502. //
  503. mov r23 = rIA32Rsrc
  504. add rIA32Ptr = rBase, r23
  505. ld8 rGDTD = [rIA32Ptr], 8 // load LDT Descriptor registers
  506. ld8 rLDTD = [rIA32Ptr], 8 // GDT Descriptor is 8 bytes after
  507. ld8 rFSD = [rIA32Ptr] // FSDescriptor is 8 bytes after
  508. //
  509. // Eflag should not be touched by stub routines...
  510. //
  511. //
  512. // Since CSD and SSD are in AR registers and since they are saved
  513. // on context switches, dont need to reload them...
  514. //
  515. //
  516. // DSD and ESD are the same as SSD, and we dont care about GSD
  517. //
  518. mov rESD = rSSD
  519. mov rDSD = rSSD
  520. mov rGSD = rSSD
  521. //
  522. // push the return address on the memory stack
  523. //
  524. //
  525. // As we never return, just push NULL...
  526. //
  527. //
  528. // Stack always points to a valid value, so decrement before putting on
  529. // return address
  530. //
  531. adds sp = -4, sp
  532. st4 [sp] = r0
  533. ARGPTR (in0)
  534. sxt4 r23 = in0
  535. mov b7 = r23
  536. br.ia.sptk b7
  537. //
  538. // Return addresses and stuff would go here, but we never return
  539. //
  540. LEAF_EXIT(GenericIACall)
  541. #endif