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.

1045 lines
25 KiB

  1. //++
  2. //
  3. // Module name:
  4. //
  5. // i64fwasm.s
  6. //
  7. // Author:
  8. //
  9. // Arad Rostampour ([email protected]) Mar-21-99
  10. //
  11. // Description:
  12. //
  13. // Assembly routines for calling into SAL, PAL, and setting up translation registers
  14. //
  15. //--
  16. #include "ksia64.h"
  17. .sdata
  18. //
  19. // HalpSalSpinLock:
  20. //
  21. // HAL private spinlock protecting generic SAL calls.
  22. //
  23. .align 128
  24. HalpSalSpinLock::
  25. data8 0
  26. //
  27. // HalpSalStateInfoSpinLock:
  28. //
  29. // HAL private spinlock protecting specific SAL STATE_INFO calls.
  30. //
  31. .align 128
  32. HalpSalStateInfoSpinLock::
  33. data8 0
  34. //
  35. // HalpMcaSpinLock
  36. //
  37. // HAL private spinlock protecting HAL internal MCA data structures and operations.
  38. // Including operations at IRQL DISPATCH_LEVEL and higher.
  39. //
  40. .align 128
  41. HalpMcaSpinLock::
  42. data8 0
  43. //
  44. // HalpInitSpinLock
  45. //
  46. // HAL private spinlock protecting HAL internal INIT data structures and operations.
  47. // Including operations at IRQL DISPATCH_LEVEL and higher.
  48. //
  49. .align 128
  50. HalpInitSpinLock::
  51. data8 0
  52. //
  53. // HalpCmcSpinLock
  54. //
  55. // HAL private spinlock protecting HAL internal CMC data structures and operations.
  56. // Including operations at IRQL DISPATCH_LEVEL and higher.
  57. //
  58. .align 128
  59. HalpCmcSpinLock::
  60. data8 0
  61. //
  62. // HalpCpeSpinLock
  63. //
  64. // HAL private spinlock protecting HAL internal CPE data structures and operations.
  65. // Including operations at IRQL DISPATCH_LEVEL and higher.
  66. //
  67. .align 128
  68. HalpCpeSpinLock::
  69. data8 0
  70. //
  71. // Definitions used in this file
  72. //
  73. // Bits to set for the Mode argument in the HalpSetupTranslationRegisters call
  74. #define SET_DTR_BIT 1
  75. #define SET_ITR_BIT 0
  76. // TR for PAL is:
  77. // ed=1, PPN=0 (to be ORed in), RWX privledge only for ring 0, dirty/accessed bit set,
  78. // cacheable memory, present bit set.
  79. #define HAL_SAL_PAL_TR_ATTRIB TR_VALUE(1,0,3,0,1,1,0,1)
  80. #define HAL_TR_ATTRIBUTE_PPN_MASK 0x0000FFFFFFFFF000
  81. .file "i64fwasm.s"
  82. // These globals are defined in i64fw.c
  83. .global HalpSalProcPointer
  84. .global HalpSalProcGlobalPointer
  85. .global HalpPhysSalProcPointer
  86. .global HalpPhysSalProcGlobalPointer
  87. .global HalpVirtPalProcPointer
  88. .global HalpPhysPalProcPointer
  89. //++
  90. //
  91. // SAL_PAL_RETURN_VALUES
  92. // HalpSalProc(
  93. // LONGLONG a0, /* SAL function ID */
  94. // LONGLONG a1, /* SAL argument */
  95. // LONGLONG a2, /* SAL argument */
  96. // LONGLONG a3, /* SAL argument */
  97. // LONGLONG a4, /* SAL argument */
  98. // LONGLONG a5, /* SAL argument */
  99. // LONGLONG a6, /* SAL argument */
  100. // LONGLONG a7 /* SAL argument */
  101. // );
  102. //
  103. // Routine Description:
  104. // This is a simple assembly wrapper that jumps directly to the SAL code. The ONLY
  105. // caller should be HalpSalCall. Other users must use the HalpSalCall API for
  106. // calling into the SAL.
  107. //
  108. // Return Values:
  109. // r8->r11 contain the 4 64-bit return values for SAL, r8 is the status
  110. //--
  111. NESTED_ENTRY(HalpSalProc)
  112. NESTED_SETUP(8,3,8,0)
  113. // copy args to outs
  114. mov out0 = a0
  115. mov out1 = a1
  116. mov out2 = a2
  117. mov out3 = a3
  118. mov out4 = a4
  119. mov out5 = a5
  120. mov out6 = a6
  121. mov out7 = a7
  122. ;;
  123. // Simply load the address and branch to it
  124. addl t1 = @gprel(HalpSalProcPointer), gp
  125. addl t2 = @gprel(HalpSalProcGlobalPointer), gp
  126. ;;
  127. mov loc2 = gp
  128. ld8 t0 = [t1]
  129. ;;
  130. ld8 gp = [t2]
  131. mov bt0 = t0
  132. rsm 1 << PSR_I // disable interrupts
  133. ;;
  134. // br.sptk.many bt0
  135. br.call.sptk brp = bt0
  136. ;;
  137. mov gp = loc2
  138. ssm 1 << PSR_I // enable interrupts
  139. ;;
  140. NESTED_RETURN
  141. NESTED_EXIT(HalpSalProc)
  142. //++
  143. //
  144. // SAL_PAL_RETURN_VALUES
  145. // HalpSalProcPhysicalEx(
  146. // LONGLONG a0, /* SAL function ID */
  147. // LONGLONG a1, /* SAL argument */
  148. // LONGLONG a2, /* SAL argument */
  149. // LONGLONG a3, /* SAL argument */
  150. // LONGLONG a4, /* SAL argument */
  151. // LONGLONG a5, /* SAL argument */
  152. // LONGLONG a6, /* SAL argument */
  153. // LONGLONG a7, /* SAL argument */
  154. // LONGLONG stack,
  155. // LONGLONG bsp
  156. // );
  157. //
  158. // Routine Description
  159. // This routine calls SAL in physical mode. The only caller should be
  160. // HalpSalCall.
  161. //
  162. //--
  163. NESTED_ENTRY(HalpSalProcPhysicalEx)
  164. NESTED_SETUP(8,2,8,0)
  165. //
  166. // Define our register aliases.
  167. //
  168. rSaveGP = t22
  169. rSaveEP = t21
  170. rSaveA7 = t20
  171. rSaveA6 = t19
  172. rSaveA5 = t18
  173. rSaveA4 = t17
  174. rSaveA3 = t16
  175. rSaveA2 = t15
  176. rSaveA1 = t14
  177. rSaveA0 = t13
  178. rSaveSp = t12
  179. rSaveBSP = t11
  180. rSavePfs = t10
  181. rSaveBrp = t9
  182. rSaveRSC = t8
  183. rSaveRNAT = t7
  184. rSavePSR = t6
  185. rNewSp = t5
  186. rNewBSP = t4
  187. rT3 = t3
  188. rT2 = t2
  189. rT1 = t1
  190. //
  191. // Pull the sp and bsp arguments off of the stack.
  192. //
  193. add rT1 = 24, sp
  194. add rT2 = 16, sp
  195. ;;
  196. ld8 rNewBSP = [rT1]
  197. ld8 rNewSp = [rT2]
  198. ;;
  199. //
  200. // Move our arguments off of the register stack and into static
  201. // registers.
  202. //
  203. mov rSaveA0 = a0
  204. mov rSaveA1 = a1
  205. mov rSaveA2 = a2
  206. mov rSaveA3 = a3
  207. mov rSaveA4 = a4
  208. mov rSaveA5 = a5
  209. mov rSaveA6 = a6
  210. mov rSaveA7 = a7
  211. //
  212. // Save copies of a few registers that will be overwritten later on.
  213. //
  214. mov rSaveSp = sp
  215. mov rSavePfs = ar.pfs
  216. mov rSaveBrp = brp
  217. //
  218. // Load the physical addresses of the SAL entry point and gp.
  219. //
  220. add rT1 = @gprel(HalpPhysSalProcPointer), gp
  221. add rT2 = @gprel(HalpPhysSalProcGlobalPointer), gp
  222. ;;
  223. ld8 rSaveEP = [rT1]
  224. ld8 rSaveGP = [rT2]
  225. ;;
  226. //
  227. // Allocate a zero sized frame so that flushrs will move the current
  228. // register stack out to memory.
  229. //
  230. alloc rT1 = 0,0,0,0
  231. ;;
  232. //
  233. // Flush the RSE.
  234. //
  235. flushrs
  236. ;;
  237. //
  238. // Save bits [31:0] and [36:35] of the current psr value.
  239. //
  240. mov rSavePSR = psr
  241. //
  242. // The .bn bit of the current psr wasn't copied to rSavePSR by the
  243. // above operation. Manually set it here so that we don't rfi
  244. // to the wrong register bank.
  245. //
  246. movl rT2 = (1 << PSR_BN)
  247. ;;
  248. or rSavePSR = rT2, rSavePSR
  249. //
  250. // Disable interrupts.
  251. //
  252. rsm (1 << PSR_I)
  253. //
  254. // Move the RSE into enforced lazy mode by manipulating ar.rsc.
  255. //
  256. mov rSaveRSC = ar.rsc
  257. mov rT1 = RSC_KERNEL_DISABLED
  258. ;;
  259. mov ar.rsc = rT1
  260. ;;
  261. //
  262. // Save the current backing store pointer (BSP) and RSE NAT collection
  263. // value.
  264. //
  265. mov rSaveBSP = ar.bsp
  266. mov rSaveRNAT = ar.rnat
  267. ;;
  268. //
  269. // Turn off psr.ic in preparation for the rfi.
  270. //
  271. rsm (1 << PSR_IC)
  272. ;;
  273. //
  274. // Build a new psr value in rT1 by using our original psr value with
  275. // .it, .dt, .rt, and .i disabled.
  276. //
  277. movl rT1 = (1 << PSR_IT) \
  278. | (1 << PSR_RT) \
  279. | (1 << PSR_DT) \
  280. | (1 << PSR_I)
  281. movl rT2 = 0xffffffffffffffff
  282. ;;
  283. xor rT1 = rT1, rT2
  284. ;;
  285. and rT1 = rT1, rSavePSR
  286. //
  287. // Make sure all of our previous psr changes take effect.
  288. //
  289. srlz.i
  290. ;;
  291. //
  292. // Load our physical mode psr into cr.ipsr.
  293. //
  294. mov cr.ipsr = rT1
  295. //
  296. // Make sure the cfm isn't corrupted when we do the rfi.
  297. //
  298. mov cr.ifs = zero
  299. ;;
  300. //
  301. // Load the physical address of our continuation label into cr.iip.
  302. //
  303. movl rT2 = HalpSalProcContinuePhysical
  304. ;;
  305. tpa rT2 = rT2
  306. ;;
  307. mov cr.iip = rT2
  308. ;;
  309. //
  310. // Do an rfi to physical mode.
  311. //
  312. rfi
  313. ;;
  314. HalpSalProcContinuePhysical:
  315. //
  316. // Switch to the physical mode stack and backing store. Note that
  317. // bspstore can only be written when the RSE is in enforced lazy
  318. // mode.
  319. //
  320. mov sp = rNewSp
  321. mov ar.bspstore = rNewBSP
  322. ;;
  323. mov ar.rnat = zero
  324. ;;
  325. //
  326. // Restore the default kernel rsc mode.
  327. //
  328. mov ar.rsc = RSC_KERNEL
  329. ;;
  330. //
  331. // Allocate a new stack frame on the new bsp.
  332. //
  333. alloc rT1 = ar.pfs,0,8,8,0
  334. //
  335. // Save the registers that aren't preserved across the procedure
  336. // call on the register stack.
  337. //
  338. mov loc0 = rSavePSR
  339. mov loc1 = rSaveRNAT
  340. mov loc2 = rSaveRSC
  341. mov loc3 = rSaveBrp
  342. mov loc4 = rSavePfs
  343. mov loc5 = rSaveBSP
  344. mov loc6 = rSaveSp
  345. mov loc7 = gp
  346. ;;
  347. //
  348. // Load the arguments for SAL_PROC.
  349. //
  350. mov out0 = rSaveA0
  351. mov out1 = rSaveA1
  352. mov out2 = rSaveA2
  353. mov out3 = rSaveA3
  354. mov out4 = rSaveA4
  355. mov out5 = rSaveA5
  356. mov out6 = rSaveA6
  357. mov out7 = rSaveA7
  358. //
  359. // Load the physical address of our return label into brp.
  360. //
  361. movl rT1 = HalpSalProcPhysicalReturnAddress
  362. ;;
  363. tpa rT1 = rT1
  364. ;;
  365. mov brp = rT1
  366. //
  367. // Load the entry point and gp of SAL_PROC.
  368. //
  369. mov bt0 = rSaveEP
  370. mov gp = rSaveGP
  371. ;;
  372. //
  373. // Call the SAL.
  374. //
  375. br.call.sptk brp = bt0
  376. ;;
  377. HalpSalProcPhysicalReturnAddress:
  378. //
  379. // Move our saved state off of the register stack and back to
  380. // static registers.
  381. //
  382. mov rSavePSR = loc0
  383. mov rSaveRNAT = loc1
  384. mov rSaveRSC = loc2
  385. mov rSaveBrp = loc3
  386. mov rSavePfs = loc4
  387. mov rSaveBSP = loc5
  388. mov rSaveSp = loc6
  389. mov gp = loc7
  390. ;;
  391. //
  392. // Stop all RSE accesses and create an empty frame on top of the
  393. // current one.
  394. //
  395. mov ar.rsc = RSC_KERNEL_DISABLED
  396. ;;
  397. alloc rT1 = 0,0,0,0
  398. ;;
  399. //
  400. // Restore our saved bspstore and rnat values.
  401. //
  402. mov ar.bspstore = rSaveBSP
  403. ;;
  404. mov ar.rnat = rSaveRNAT
  405. //
  406. // Restore the stack pointer.
  407. //
  408. mov sp = rSaveSp
  409. ;;
  410. //
  411. // Turn off psr.ic in preparation for the rfi back to virtual
  412. // mode.
  413. //
  414. rsm (1 << PSR_IC)
  415. ;;
  416. movl rT1 = HalpSalProcCompletePhysical
  417. ;;
  418. //
  419. // Make sure our psr change has taken effect.
  420. //
  421. srlz.i
  422. ;;
  423. //
  424. // Load our continuation label address into cr.iip and our saved
  425. // psr value into cr.ipsr. Also set cr.ifs so that CFM won't be
  426. // corrupted by the rfi.
  427. //
  428. mov cr.iip = rT1
  429. mov cr.ipsr = rSavePSR
  430. mov cr.ifs = zero
  431. ;;
  432. //
  433. // Do an rfi back to virtual mode.
  434. //
  435. rfi
  436. ;;
  437. HalpSalProcCompletePhysical:
  438. //
  439. // Restore our RSC state.
  440. //
  441. mov ar.rsc = rSaveRSC
  442. ;;
  443. //
  444. // Restore our saved PFS value along with our return pointer and
  445. // return to the caller.
  446. //
  447. mov ar.pfs = rSavePfs
  448. mov brp = rSaveBrp
  449. ;;
  450. br.ret.sptk brp
  451. NESTED_EXIT(HalpSalProcPhysicalEx)
  452. //++
  453. //
  454. // SAL_PAL_RETURN_VALUES
  455. // HalpPalProc(
  456. // LONGLONG a0, /* PAL function ID */
  457. // LONGLONG a1, /* PAL argument */
  458. // LONGLONG a2, /* PAL argument */
  459. // LONGLONG a3 /* PAL argument */
  460. // );
  461. //
  462. // Routine Description
  463. // This routine sets up the correct registers for input into PAL depending on
  464. // if the call uses static or stacked registers, turns off interrupts, ensures
  465. // the correct bank registers are being used and calls into the PAL. The ONLY
  466. // caller should be HalpPalCall. Other users must use the HalpPalCall API for
  467. // calling into the PAL.
  468. //
  469. // Return Values:
  470. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  471. //--
  472. NESTED_ENTRY(HalpPalProc)
  473. NESTED_SETUP(4,3,4,0)
  474. PROLOGUE_END
  475. // For both the static and stacked register conventions, load r28 with FunctionID
  476. mov r28 = a0
  477. // If static register calling convention (1-255, 512-767), copy arguments to r29->r31
  478. // Otherwise, copy to out0->out3 so they are in r32->r35 in PAL_PROC
  479. mov t0 = a0
  480. ;;
  481. shr t0 = t0, 8
  482. ;;
  483. tbit.z pt0, pt1 = t0, 0
  484. ;;
  485. //
  486. // Static proc: do br not call
  487. //
  488. (pt0) mov r29 = a1
  489. (pt0) mov r30 = a2
  490. (pt0) mov r31 = a3
  491. //
  492. // Stacked call
  493. //
  494. (pt1) mov out0 = a0
  495. (pt1) mov out1 = a1
  496. (pt1) mov out2 = a2
  497. (pt1) mov out3 = a3
  498. // Load up the address of PAL_PROC and call it
  499. addl t1 = @gprel(HalpVirtPalProcPointer), gp
  500. ;;
  501. ld8 t0 = [t1]
  502. ;;
  503. mov bt0 = t0
  504. // Call into PAL_PROC
  505. (pt0) addl t1 = @ltoff(PalReturn), gp
  506. ;;
  507. (pt0) ld8 t0 = [t1]
  508. ;;
  509. (pt0) mov brp = t0
  510. ;;
  511. // Disable interrupts
  512. DISABLE_INTERRUPTS(loc2)
  513. ;;
  514. srlz.d
  515. ;;
  516. (pt0) br.sptk.many bt0
  517. ;;
  518. (pt1) br.call.sptk brp = bt0
  519. ;;
  520. PalReturn:
  521. // Restore the interrupt state
  522. RESTORE_INTERRUPTS(loc2)
  523. ;;
  524. NESTED_RETURN
  525. NESTED_EXIT(HalpPalProc)
  526. //++
  527. //
  528. // SAL_PAL_RETURN_VALUES
  529. // HalpPalProcPhysicalStatic(
  530. // LONGLONG a0, /* PAL function ID */
  531. // LONGLONG a1, /* PAL argument */
  532. // LONGLONG a2, /* PAL argument */
  533. // LONGLONG a3 /* PAL argument */
  534. // );
  535. //
  536. // Routine Description
  537. // This routine sets up the correct registers for input into PAL turns off interrupts,
  538. // ensures the correct bank registers are being used and calls into the PAL in PHYSICAL
  539. // mode since some of the calls require it. The ONLY caller should be HalpPalCall.
  540. // Other users must use the HalpPalCall API for calling into the PAL.
  541. //
  542. // Return Values:
  543. // r8->r11 contain the 4 64-bit return values for PAL, r8 is the status
  544. //--
  545. NESTED_ENTRY(HalpPalProcPhysicalStatic)
  546. NESTED_SETUP(4,5,0,0)
  547. //
  548. // Aliases
  549. //
  550. rSaveGP = t21
  551. rSaveEP = t20
  552. // r28 = t19 is reserved for PAL calling convention.
  553. rSavePSR = t18
  554. rSaveRSC = loc3
  555. rT3 = t3
  556. rT2 = t2
  557. rT1 = t1
  558. add rT3 = @gprel(HalpPhysPalProcPointer), gp
  559. ;;
  560. ld8 rSaveEP = [rT3]
  561. ;;
  562. //
  563. // Flush RSE and Turn Off interrupts
  564. //
  565. flushrs
  566. mov rSavePSR = psr
  567. movl rT2 = (1 << PSR_BN)
  568. mov rSaveRSC = ar.rsc
  569. mov rT1 = RSC_KERNEL_DISABLED
  570. ;;
  571. or rSavePSR = rT2, rSavePSR // psr.bn stays on
  572. rsm (1 << PSR_I)
  573. mov ar.rsc = rT1
  574. ;;
  575. // Turn Off Interrupt Collection
  576. rsm (1 << PSR_IC)
  577. //
  578. // IC = 0; I = 0;
  579. //
  580. //
  581. // IIP = HalpPalProcContinuePhysicalStatic: IPSR is physical
  582. //
  583. movl rT1 = (1 << PSR_IT) | (1 << PSR_RT) | (1 << PSR_DT) | (1 << PSR_I)
  584. movl rT2 = 0xffffffffffffffff
  585. ;;
  586. xor rT1 = rT1, rT2
  587. ;;
  588. and rT1 = rT1, rSavePSR // rT1 = old PSR & zero it, dt, rt, i
  589. srlz.i
  590. ;;
  591. mov cr.ipsr = rT1
  592. mov cr.ifs = zero
  593. ;;
  594. movl rT2 = HalpPalProcContinuePhysicalStatic
  595. ;;
  596. tpa rT2 = rT2 // phys address of new ip
  597. ;;
  598. mov cr.iip = rT2
  599. ;;
  600. rfi
  601. ;;
  602. //
  603. // Now in physical mode, ic = 1, i = 0
  604. //
  605. HalpPalProcContinuePhysicalStatic:
  606. // Setup Arguments
  607. mov bt0 = rSaveEP
  608. mov loc2 = rSavePSR // save PSR value
  609. mov r28 = a0
  610. mov r29 = a1
  611. mov r30 = a2
  612. mov r31 = a3
  613. ;;
  614. movl rT1 = HalpPalProcPhysicalStaticReturnAddress
  615. ;;
  616. tpa rT1 = rT1
  617. ;;
  618. mov brp = rT1
  619. ;;
  620. br.cond.sptk bt0
  621. ;;
  622. HalpPalProcPhysicalStaticReturnAddress:
  623. rsm (1 << PSR_IC)
  624. ;;
  625. movl rT1 = HalpPalProcCompletePhysicalStatic
  626. ;;
  627. srlz.i
  628. ;;
  629. mov ar.rsc = rSaveRSC
  630. mov cr.iip = rT1
  631. mov cr.ipsr = loc2
  632. mov cr.ifs = zero
  633. ;;
  634. rfi
  635. ;;
  636. //
  637. // Now in virtual mode, ic = 1, i = 1
  638. //
  639. HalpPalProcCompletePhysicalStatic:
  640. //
  641. // Restore pfs, brp and return
  642. //
  643. NESTED_RETURN
  644. NESTED_EXIT(HalpPalProcPhysicalStatic)
  645. //++
  646. //
  647. // SAL_PAL_RETURN_VALUES
  648. // HalpPalProcPhysicalStacked(
  649. // LONGLONG a0, /* PAL function ID */
  650. // LONGLONG a1, /* PAL argument */
  651. // LONGLONG a2, /* PAL argument */
  652. // LONGLONG a3, /* PAL argument */
  653. // LONGLONG StackPointer,
  654. // LONGLONG BackingStorePointer
  655. // );
  656. //
  657. // Routine Description
  658. // This routine calls PAL in physical mode for the stacked calling
  659. // convention. The ONLY caller should be HalpPalCall. Other users must
  660. // use the HalpPalCall API for calling into the PAL.
  661. //
  662. //--
  663. NESTED_ENTRY(HalpPalProcPhysicalStacked)
  664. NESTED_SETUP(6,2,0,0)
  665. //
  666. // Aliases
  667. //
  668. rSaveGP = t21
  669. rSaveEP = t20
  670. // r28 = t19 is reserved for PAL calling convention.
  671. rSaveA3 = t18
  672. rSaveA2 = t17
  673. rSaveA1 = t16
  674. rSaveA0 = t15
  675. rSaveSp = t14
  676. rSaveBSP = t13
  677. rSavePfs = t12
  678. rSaveBrp = t11
  679. rSaveRSC = t10
  680. rSaveRNAT = t9
  681. rSavePSR = t8
  682. rNewSp = t7
  683. rNewBSP = t6
  684. rT3 = t3
  685. rT2 = t2
  686. rT1 = t1
  687. // Save Arguments in static Registers
  688. mov rSaveA0 = a0
  689. mov rSaveA1 = a1
  690. mov rSaveA2 = a2
  691. mov rSaveA3 = a3
  692. mov rSaveSp = sp
  693. mov rSavePfs = ar.pfs
  694. mov rSaveBrp = brp
  695. //
  696. // Setup Physical sp, bsp
  697. //
  698. add rT3 = @gprel(HalpPhysPalProcPointer), gp
  699. ;;
  700. mov rNewSp = a4
  701. mov rNewBSP = a5
  702. ld8 rSaveEP = [rT3]
  703. ;;
  704. // tpa rSaveEP = rSaveEP
  705. // Allocate a zero-sized frame
  706. // ;;
  707. alloc rT1 = 0,0,0,0
  708. // Flush RSE and Turn Off interrupts
  709. ;;
  710. flushrs
  711. ;;
  712. mov rSavePSR = psr
  713. movl rT2 = (1 << PSR_BN)
  714. ;;
  715. or rSavePSR = rT2, rSavePSR // psr.bn stays on
  716. rsm (1 << PSR_I)
  717. mov rSaveRSC = ar.rsc
  718. // Flush RSE to enforced lazy mode by clearing both RSC.mode bits
  719. mov rT1 = RSC_KERNEL_DISABLED
  720. ;;
  721. mov ar.rsc = rT1
  722. ;;
  723. //
  724. // save RSC, RNAT, BSP, PSR, SP in the allocated space during initialization
  725. //
  726. mov rSaveBSP = ar.bsp
  727. mov rSaveRNAT = ar.rnat
  728. ;;
  729. // Turn Off Interrupt Collection
  730. rsm (1 << PSR_IC)
  731. ;;
  732. //
  733. // IC = 0; I = 0;
  734. //
  735. //
  736. // IIP = HalpPalProcContinuePhysicalStacked: IPSR is physical
  737. //
  738. movl rT1 = (1 << PSR_IT) | (1 << PSR_RT) | (1 << PSR_DT) | (1 << PSR_I)
  739. movl rT2 = 0xffffffffffffffff
  740. ;;
  741. xor rT1 = rT1, rT2
  742. ;;
  743. and rT1 = rT1, rSavePSR // rT1 = old PSR & zero it, dt, rt, i
  744. srlz.i
  745. ;;
  746. mov cr.ipsr = rT1
  747. mov cr.ifs = zero
  748. ;;
  749. movl rT2 = HalpPalProcContinuePhysicalStacked
  750. ;;
  751. tpa rT2 = rT2 // phys address of new ip
  752. ;;
  753. mov cr.iip = rT2
  754. ;;
  755. rfi
  756. ;;
  757. //
  758. // Now in physical mode, ic = 1, i = 0
  759. //
  760. HalpPalProcContinuePhysicalStacked:
  761. //
  762. // Switch to new bsp, sp
  763. //
  764. mov sp = rNewSp
  765. mov ar.bspstore = rNewBSP
  766. ;;
  767. mov ar.rnat = zero
  768. ;;
  769. //
  770. // Enable RSC
  771. //
  772. mov ar.rsc = RSC_KERNEL
  773. ;;
  774. //
  775. // Allocate frame on new bsp
  776. //
  777. alloc rT1 = ar.pfs,0,7,4,0
  778. //
  779. // Save caller's state in register stack
  780. //
  781. mov loc0 = rSaveRNAT
  782. mov loc1 = rSaveSp
  783. mov loc2 = rSaveBSP
  784. mov loc3 = rSaveRSC
  785. mov loc4 = rSaveBrp
  786. mov loc5 = rSavePfs
  787. mov loc6 = rSavePSR
  788. ;;
  789. // Setup Arguments
  790. mov r28 = rSaveA0
  791. mov out0 = rSaveA0
  792. mov out1 = rSaveA1
  793. mov out2 = rSaveA2
  794. mov out3 = rSaveA3
  795. movl rT1 = HalpPalProcPhysicalStackedReturnAddress
  796. ;;
  797. tpa rT1 = rT1
  798. ;;
  799. mov brp = rT1
  800. // mov gp = rSaveGP
  801. mov bt0 = rSaveEP
  802. ;;
  803. br.call.sptk brp = bt0
  804. ;;
  805. HalpPalProcPhysicalStackedReturnAddress:
  806. //
  807. // In physical mode: switch to virtual
  808. //
  809. //
  810. // Restore saved state
  811. //
  812. mov rSaveRNAT = loc0
  813. mov rSaveSp = loc1
  814. mov rSaveBSP = loc2
  815. mov rSaveRSC = loc3
  816. mov rSaveBrp = loc4
  817. mov rSavePfs = loc5
  818. mov rSavePSR = loc6
  819. ;;
  820. //
  821. // Restore BSP, SP
  822. //
  823. ;;
  824. mov ar.rsc = RSC_KERNEL_DISABLED
  825. ;;
  826. alloc rT1 = 0,0,0,0
  827. ;;
  828. mov ar.bspstore = rSaveBSP
  829. ;;
  830. mov ar.rnat = rSaveRNAT
  831. mov sp = rSaveSp
  832. ;;
  833. rsm (1 << PSR_IC)
  834. ;;
  835. movl rT1 = HalpPalProcCompletePhysicalStacked
  836. ;;
  837. srlz.i
  838. ;;
  839. mov cr.iip = rT1
  840. mov cr.ipsr = rSavePSR
  841. mov cr.ifs = zero
  842. ;;
  843. rfi
  844. ;;
  845. //
  846. // Now in virtual mode, ic = 1, i = 1
  847. //
  848. HalpPalProcCompletePhysicalStacked:
  849. //
  850. // Restore psf, brp and return
  851. //
  852. mov ar.rsc = rSaveRSC
  853. ;;
  854. mov ar.pfs = rSavePfs
  855. mov brp = rSaveBrp
  856. ;;
  857. br.ret.sptk brp
  858. NESTED_EXIT(HalpPalProcPhysicalStacked)