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.

996 lines
33 KiB

  1. //###########################################################################
  2. //**
  3. //** Copyright (C) 1996-98 Intel Corporation. All rights reserved.
  4. //**
  5. //** The information and source code contained herein is the exclusive
  6. //** property of Intel Corporation and may not be disclosed, examined
  7. //** or reproduced in whole or in part without explicit written authorization
  8. //** from the company.
  9. //**
  10. //###########################################################################
  11. //-----------------------------------------------------------------------------
  12. // Version control information follows.
  13. //
  14. // $Header: I:/DEVPVCS/OSMCA/osmchk.s_v 2.1 05 Mar 1999 12:59:42 smariset $
  15. // $Log: I:/DEVPVCS/OSMCA/osmchk.s_v $
  16. //
  17. // Rev 2.0 Dec 11 1998 11:42:18 khaw
  18. //Post FW 0.5 release sync-up
  19. //
  20. // Rev 1.4 12 Oct 1998 14:05:20 smariset
  21. //gp fix up work around
  22. //
  23. ///////////////////////////////////////////////////////////////////////////////
  24. //
  25. // Module Name: OSMCHK.ASM - Merced OS Machine Check Abort Dispatcher
  26. //
  27. // Description:
  28. // Merced OS Machine Check Abort Stub to OSMCA "C" frame work. If
  29. // we find a TLB related error, we cannot switch to virtual mode in
  30. // the OS. All TLB related errors will need system reboot after
  31. // storing the errors to a persistence storage media (HD or Flash).
  32. //
  33. // HalpOsMcaDispatch - Main
  34. //
  35. // Target Platform: Merced
  36. //
  37. // Reuse: None
  38. //
  39. ////////////////////////////////////////////////////////////////////////////M//
  40. #include "ksia64.h"
  41. #include "fwglobal.h"
  42. GLOBAL_FUNCTION(HalpOsMcaDispatch)
  43. GLOBAL_FUNCTION(HalpMCAEnable)
  44. GLOBAL_FUNCTION(HalpMcaHandler)
  45. GLOBAL_FUNCTION(HalpAcquireMcaSpinLock)
  46. GLOBAL_FUNCTION(HalpReleaseMcaSpinLock)
  47. .text
  48. //++
  49. // Name: HalpOsMcaDispatch()
  50. //
  51. // Routine Description:
  52. //
  53. // This is the OS call back handler, which is only exported to the SAL for call back
  54. // during MCA errors. This handler will dispatch to the appropriate MCA procedure.
  55. //
  56. // Sets up virtual->physical address translation
  57. // 0x00100000->0x00100000 in dtr1/itr1 for OS_MCA.
  58. //
  59. // Arguments:
  60. //
  61. // None
  62. //
  63. // On entry:
  64. //
  65. // This function is called:
  66. // - in physical mode for uncorrected or correctable MCA events,
  67. // - RSE enforced in lazy mode,
  68. // - Processor resources:
  69. // PSR.dt = 0, PSR.it = 0, PSR.rt = 0 - Physical mode.
  70. // PSR.ic = 0, PSR.i = 0 - Interrupt resources collection and interrupt disabled.
  71. // PSR.mc = 1 - Machine Checks masked
  72. // PSR.mfl = 0 - low fp disabled.
  73. // GR1 : OS_MCA Global Pointer (GP) registered by OS: OS's GP.
  74. // GR2-7: Unspecified.
  75. // GR8 : Physical address of the PAL_PROC entrypoint.
  76. // GR9 : Physical address of the SAL_PROC entrypoint.
  77. // GR10 : Physical address value of the SAL Global Pointer: SAL's GP.
  78. // GR11 : Rendezvous state information, defined as:
  79. // 0 - Rendezvous of other processors was not required by
  80. // PAL_CHECK and as such was not done.
  81. // 1 - All other processors in the system were successfully
  82. // rendezvous using MC_RENDEZVOUS interrupt.
  83. // 2 - All other processors in the system were successfully
  84. // rendezvous using a combination of MC_RENDEZVOUS
  85. // interrupt and INIT.
  86. // -1 - Rendezvous of other processors was required by PAL
  87. // but was unsuccessful.
  88. // GR12 : Return address to a location within SAL_CHECK.
  89. // GR17 : Pointer to processor minimum state saved memory location.
  90. // GR18 : Processor state as defined below:
  91. // D0-D5: Reserved
  92. // D6-D31: As defined in PAL EAS
  93. // D60-D63: As defined in PAL EAS
  94. // D32-D47: Size in bytes of processor dynamic state
  95. // D48-D59: Reserved.
  96. // GR19 : Return address to a location within PAL_CHECK.
  97. // BR0 : Unspecified.
  98. //
  99. // Return State:
  100. //
  101. // Note : The OS_MCA procedure may or may not return to SAL_CHECK
  102. // in the case of uncorrected machine checks.
  103. // If it returns to SAL, the runtime convention requires that
  104. // it sets appropriate values in the Min-State area pointed
  105. // to by GR12 for continuing execution at the interrupted
  106. // context or at a new context.
  107. // Furthermore, the OS_MCA procedure must restore the
  108. // processor state to the same state as on entry except as:
  109. // GR1-7 : Unspecified.
  110. // GR8 : Return status
  111. // 0 [= SAL_STATUS_SUCCESS] - Error has been corrected
  112. // by OS_MCA.
  113. // -1 - Error has not been corrected by OS_MCA and
  114. // SAL must warm boot the system.
  115. // -2 - Error has not been corrected by OS_MCA and
  116. // SAL must cold boot the system.
  117. // -3 - Error has not been corrected by OS_MCA and
  118. // SAL must halt the system.
  119. // GR9 : Physical address value for SAL's GP.
  120. // GR10 : Context flag
  121. // 0 - Return will be to the same context.
  122. // 1 - Return will be to a new context.
  123. // GR11-21: Unspecified.
  124. // GR22 : Pointer to a structure containing new values of registers
  125. // in the Min-State Save area.
  126. // OS_MCA must supply this parameter even if it does not
  127. // change the register values in the Min-State Save areas.
  128. // GR23-31: Unspecified.
  129. // BR0 : Unspecified.
  130. // PSR.mc : May be either 0 or 1.
  131. //--
  132. HalpOsMcaDispatch::
  133. // aliases for known registers:
  134. rPalProcEntryPoint = r8
  135. rSalProcEntryPoint = r9
  136. rSalGlobalPointer = r10
  137. rRendezVousResult = r11
  138. rSalReturnAddress = r12
  139. rProcMinStateSavePtr = r17
  140. rProcStateParameter = r18
  141. rPalCheckReturnAddress = r19
  142. rEventResources = t22
  143. rPcrPhysicalAddress = t6
  144. //
  145. // - Flag the processor as "InOsMca":
  146. // KiPcr.InOsMca = 1
  147. //
  148. // - Update KiPcr.McaPTOM to point to TopOfMemory,
  149. // Memory after Processor Minimum State Save area.
  150. //
  151. // - Update processor McaResource.SalToOsHandOff
  152. //
  153. // - Update local rPcrMcaStateDump before calling osMcaProcStateDump.
  154. //
  155. mov rEventResources = PcOsMcaResourcePtr
  156. movl t21 = KiPcr
  157. ;;
  158. tpa rPcrPhysicalAddress = t21 // Calculate physical address of PCR
  159. mov t19 = SerSalToOsHandOff
  160. mov t1 = 0x1
  161. ;;
  162. add t0 = rPcrPhysicalAddress, rEventResources
  163. sub t21 = rPcrPhysicalAddress, t21
  164. add t16 = TOM, rProcMinStateSavePtr
  165. ;;
  166. ld8 rEventResources = [t0], PcInOsMca-PcOsMcaResourcePtr
  167. mov t18 = SerPTOM
  168. add t20 = 0x8, t19
  169. ;;
  170. xchg1 t1 = [t0], t1
  171. add rEventResources = rEventResources, t21 // Calculate the physical address of the OsMcaResources
  172. add t21 = 0x10, t19
  173. ;;
  174. add t18 = rEventResources, t18
  175. add t19 = rEventResources, t19
  176. add t20 = rEventResources, t20
  177. add t21 = rEventResources, t21
  178. ;;
  179. ld8 t17 = [t16]
  180. st8 [t19] = rPalProcEntryPoint, 0x18
  181. add t0 = SerStateDumpPhysical, rEventResources
  182. ;;
  183. st8 [t18] = t17
  184. st8 [t20] = rSalProcEntryPoint, 0x18
  185. st8 [t21] = rSalGlobalPointer, 0x18
  186. ;;
  187. st8 [t19] = rRendezVousResult
  188. st8 [t20] = rSalReturnAddress
  189. st8 [t21] = rProcMinStateSavePtr
  190. ld8 t0 = [t0] // McaStateDump
  191. ;;
  192. //
  193. // Save in preserved registers:
  194. // - pointer to processor minimum state save area,
  195. // - processor state parameter
  196. // - PAL_CHECK return address.
  197. // s0 [=r4] <- r17,
  198. // s1 [=r5] <- r18,
  199. // s2 [=r6] <- r19
  200. //
  201. SaveRs(rProcMinStateSavePtr, rProcStateParameter, rPalCheckReturnAddress)
  202. //
  203. // Save register resources in myStateDump[].
  204. //
  205. br.dpnt osMcaProcStateDump
  206. ;;
  207. osMcaDoneDump::
  208. //
  209. // If we have a TLB error, we cannot enable translation
  210. //
  211. tbit.nz.unc pt0,p0=s1, 60 // PSP.tc=60
  212. (pt0) br.dpnt ResetNow
  213. ;;
  214. //
  215. // Initialize current sp and ar.bsp and ar.bspstore
  216. //
  217. // KiPcr.McaStackFrame[0] = ar.rsc
  218. // KiPcr.McaStackFrame[1] = ar.pfs
  219. // KiPcr.McaStackFrame[2] = ar.ifs
  220. // KiPcr.McaStackFrame[3] = ar.bspstore
  221. // KiPcr.McaStackFrame[4] = ar.rnat
  222. // ar.bspstore = t0 [=KiPcr.McaBspStore]
  223. // KiPcr.McaStackFrame[5] = ar.bsp - KiPcr.McaBspStore
  224. // [BUGBUG ?? : should be ar.bsptore=KiPcr.McaStackFrame[3]]
  225. // sp = KiPcr.McaStack
  226. //
  227. movl t21 = KiPcr + PcOsMcaResourcePtr
  228. ;;
  229. tpa t0 = t21 // Calculate physical address of PCR OsMcaResourcePtr
  230. mov t1 = SerStackFrame
  231. ;;
  232. sub t16 = SerBackStore, t21
  233. sub t1 = t1, t21
  234. ;;
  235. add t16 = t0, t16
  236. add t1 = t0, t1
  237. ld8 rEventResources = [t0], PcInitialBStore - PcOsMcaResourcePtr
  238. ;;
  239. add t16 = rEventResources, t16 // Calculate physical address of the new BSP
  240. mov t21 = t0 // t21 now points to InitialBStore in the PCR
  241. ;;
  242. add t1 = rEventResources, t1 // Calculate the physical address of the Stack Frame
  243. ld8 t0 = [t16], SerStack - SerBackStore
  244. ;;
  245. SwIntCxt( t4, t1, t0 )
  246. ;;
  247. st8 [t21] = t0, PcInitialStack - PcInitialBStore // Save the InitialBStore in the PCR
  248. ld8 t1 = [t16], SerBackStoreLimit - SerStack // Get inital MCA stack
  249. ;;
  250. st8 [t21] = t1, PcBStoreLimit - PcInitialStack
  251. ld8 t0 = [t16], SerStackLimit - SerBackStoreLimit
  252. ;;
  253. add t1 = -STACK_SCRATCH_AREA, t1
  254. st8 [t21] = t0, PcStackLimit - PcBStoreLimit // Save BStore limit
  255. ld8 t18 = [t16]
  256. ;;
  257. mov sp = t1
  258. st8 [t21] = t18
  259. ;;
  260. EnableTranslation::
  261. // let us switch to virtual mode
  262. //
  263. // Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
  264. //
  265. // Make sure interrupts are disabled and that we are running on bank 1.
  266. //
  267. rsm 1 << PSR_I
  268. bsw.1
  269. ;;
  270. mov ar.rsc = r0 // put RSE in lazy mode and use kernel mode stores.
  271. //
  272. // psr mask prepration, warning we will have a problem with PMI here
  273. //
  274. movl t0 = MASK_IA64(PSR_BN,1) | MASK_IA64(PSR_IC,1) |MASK_IA64(PSR_DA,1) | MASK_IA64(PSR_IT,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1) | MASK_IA64(PSR_MC,1);;
  275. mov t1 = psr;;
  276. or t0 = t0, t1
  277. movl t1 = VirtualSwitchDone;;
  278. mov cr.iip = t1
  279. mov cr.ipsr = t0;;
  280. rfi
  281. ;;
  282. VirtualSwitchDone::
  283. // done with enabling address translation
  284. // call our handler
  285. movl t0 = HalpMcaHandler;;
  286. mov b6 = t0;;
  287. br.call.dpnt b0=b6
  288. ;;
  289. DisableTranslation::
  290. // psr mask prepration
  291. rsm MASK_IA64(PSR_IC,1);;
  292. movl t0 = MASK_IA64(PSR_DA,1) | MASK_IA64(PSR_IT,1) | MASK_IA64(PSR_RT,1) | MASK_IA64(PSR_DT,1);;
  293. movl t1=0xffffffffffffffff;;
  294. xor t0=t0,t1;;
  295. mov t1=psr;;
  296. and t0=t0,t1
  297. movl t1=BeginOsMcaRestore;;
  298. tpa t1=t1;;
  299. mov cr.iip=t1;;
  300. mov cr.ipsr = t0;;
  301. rfi
  302. ;;
  303. BeginOsMcaRestore::
  304. // restore the original stack frame here
  305. mov t16 = SerStackFrame
  306. movl t21 = KiPcr + PcOsMcaResourcePtr
  307. ;;
  308. tpa t1 = t21 // Calculate physical address of PCR OsMcaResourcePtr
  309. sub t16 = t16, t21
  310. sub t0 = SerStateDumpPhysical, t21
  311. ;;
  312. ld8 rEventResources = [t1]
  313. add t16 = t1, t16
  314. add t0 = t1, t0
  315. ;;
  316. add t16 = rEventResources, t16 // Calculate the physical address of the Stack Frame
  317. add t0 = rEventResources, t0 // Calculate the physical address of the State Dump pointer.
  318. ;;
  319. ld8 t0 = [t0];
  320. movl t4 = PSRmcMask
  321. ;;
  322. RtnIntCxt( t4, t1, t16 ) // switch from interrupt context -> RSC mgmt.
  323. ;;
  324. //
  325. // let us restore all the registers from our PSI structure
  326. //
  327. mov t6 = gp
  328. br.dpnt osMcaProcStateRestore
  329. ;;
  330. osMcaDoneRestore::
  331. // Pal requires DFH of 0
  332. rsm 1 << PSR_DFH
  333. ;;
  334. rsm 1 << PSR_MFL // just restoring to original state only
  335. ;;
  336. srlz.d
  337. ;;
  338. //
  339. // - Restore processor state from OsToSalHandOff.
  340. //
  341. // - Branch back to SALE_CHECK.
  342. mov t1 = PcOsMcaResourcePtr
  343. movl t21 = KiPcr
  344. ;;
  345. tpa rPcrPhysicalAddress = t21 // Calculate physical address of PCR
  346. ;;
  347. add t0 = rPcrPhysicalAddress, t1
  348. sub t21 = SerOsToSalHandOff, t21
  349. ;;
  350. ld8 t1 = [t0], PcInOsMca-PcOsMcaResourcePtr
  351. add t21 = t21, rPcrPhysicalAddress
  352. ;;
  353. add t1 = t1, t21 // Calculate the physical address of the OsMcaResources->SalToOSHandOff
  354. ;;
  355. add t16 = 0x8, t1
  356. add t17 = 0x10, t1
  357. ;;
  358. ld8 r8 = [t1], 0x18 // result of error handling
  359. ld8 r9 = [t16], 0x18 // physical SAL's GP value
  360. ld8 r22 = [t17] // new Processor Min-State Save Ptr
  361. ;;
  362. ld8 t1 = [t1] // SAL return address
  363. ld8 r10 = [t16] // New Context Switch Flag
  364. xchg1 t0 = [t0], r0 // KiPcr.InOsMca = 0
  365. ;;
  366. mov b0 = t1
  367. br.dpnt b0 // Return to SALE_CHECK
  368. ;;
  369. StayInPhysicalMode::
  370. // we have to reboot the machine, assume the log is already there in NVM
  371. // OS can read the log next time when it comes around. Or OS can try to
  372. // run in physical mode as well.
  373. ResetNow::
  374. // do EFI system reset here...
  375. // Go to BugCheck (in physical mode).
  376. // Out to Port 80: Fatal TLB error
  377. //
  378. Thyself::
  379. br Thyself // loop for safety
  380. ;;
  381. //EndMain//////////////////////////////////////////////////////////////////////
  382. //++
  383. // Name:
  384. // osMcaProcStateDump()
  385. //
  386. // Stub Description:
  387. //
  388. // This stub dumps the processor state during MCHK to a data area
  389. //
  390. // On Entry:
  391. //
  392. // t0 = rPcrMcaStateDump.
  393. //
  394. // Return Value:
  395. //
  396. // None.
  397. //
  398. //--
  399. osMcaProcStateDump::
  400. // Get and save GR0-31 from Proc. Min. State Save Area to SAL PSI
  401. // TF: ASSERT( t0 == rPcrMcaStateDump )
  402. //save BRs
  403. add t2=Inc8,t0 // duplicate t0 in t2
  404. add t4=2*Inc8,t0 // duplicate t0 in t2
  405. mov t1=b0
  406. mov t3=b1
  407. mov t5=b2;;
  408. st8 [t0]=t1,3*Inc8
  409. st8 [t2]=t3,3*Inc8
  410. st8 [t4]=t5,3*Inc8;;
  411. mov t1=b3
  412. mov t3=b4
  413. mov t5=b5;;
  414. st8 [t0]=t1,3*Inc8
  415. st8 [t2]=t3,3*Inc8
  416. st8 [t4]=t5,3*Inc8;;
  417. mov t1=b6
  418. mov t3=b7;;
  419. st8 [t0]=t1,2*Inc8
  420. st8 [t2]=t3,2*Inc8;;
  421. cSaveCRs::
  422. // save CRs
  423. add t2=Inc8,t0 // duplicate t0 in t2
  424. add t4=2*Inc8,t0 // duplicate t0 in t2
  425. mov t1=cr0 // cr.dcr
  426. mov t3=cr1 // cr.itm
  427. mov t5=cr2;; // cr.iva
  428. st8 [t0]=t1,8*Inc8
  429. st8 [t2]=t3,3*Inc8
  430. st8 [t4]=t5,3*Inc8;; // 48 byte increments
  431. mov t1=cr8;; // cr.pta
  432. st8 [t0]=t1,Inc8*8;; // 64 byte increments
  433. // Reading interruption registers when PSR.ic=1 causes an illegal operation fault
  434. mov t1=psr;;
  435. tbit.nz.unc pt0,p0=t1,PSRic;; // PSI Valid Log bit pos. test
  436. (pt0) st8 [t0]=r0;;
  437. (pt0) adds t0 = 0x30*Inc8, t0 // cr16->cr64 increment
  438. (pt0) br.dpnt SkipIntrRegs
  439. ;;
  440. add t2=Inc8,t0 // duplicate t0 in t2
  441. add t4=2*Inc8,t0 // duplicate t0 in t4
  442. mov t1=cr16 // cr.ipsr
  443. mov t3=cr17 // cr.isr
  444. mov t5=r0;; // cr.ida => cr18
  445. st8 [t0]=t1,3*Inc8
  446. st8 [t2]=t3,3*Inc8
  447. st8 [t4]=t5,3*Inc8;;
  448. mov t1=cr19 // cr.iip
  449. mov t3=cr20 // cr.ifa
  450. mov t5=cr21;; // cr.iitr
  451. st8 [t0]=t1,3*Inc8
  452. st8 [t2]=t3,3*Inc8
  453. st8 [t4]=t5,3*Inc8;;
  454. mov t1=cr22 // cr.iipa
  455. mov t3=cr23 // cr.ifs
  456. mov t5=cr24;; // cr.iim
  457. st8 [t0]=t1,3*Inc8
  458. st8 [t2]=t3,3*Inc8
  459. st8 [t4]=t5,3*Inc8;;
  460. mov t1=cr25;; // cr.iha
  461. st8 [t0]=t1;;
  462. adds t0 = 0x27*Inc8, t0;; // cr25->cr64 byte increment
  463. SkipIntrRegs::
  464. mov t1=cr64;; // cr.lid
  465. st8 [t0]=t1,Inc8 //
  466. mov t1=cr65;; // cr.ivr
  467. st8 [t0]=t1,Inc8
  468. mov t1=cr66;; // cr.tpr
  469. st8 [t0]=t1,Inc8
  470. mov t1=r0;; // cr.eoi
  471. st8 [t0]=t1,Inc8 //
  472. mov t1=r0;; // cr.irr0
  473. st8 [t0]=t1,Inc8
  474. mov t1=r0;; // cr.irr1
  475. st8 [t0]=t1,Inc8
  476. mov t1=r0;; // cr.irr2
  477. st8 [t0]=t1,Inc8
  478. mov t1=r0;; // cr.irr3
  479. st8 [t0]=t1,Inc8
  480. mov t1=r0;; // cr.itv
  481. st8 [t0]=t1,Inc8
  482. mov t1=r0;; // cr.pmv
  483. st8 [t0]=t1,Inc8
  484. mov t1=r0;; // cr.cmcv
  485. st8 [t0]=t1,6*Inc8
  486. mov t1=r0;; // cr.lrr0
  487. st8 [t0]=t1,Inc8
  488. mov t1=r0;; // cr.lrr1
  489. st8 [t0]=t1;;
  490. adds t0 = 0x2f*Inc8, t0;; // cr81->ar [128]
  491. cSaveARs::
  492. // save ARs
  493. add t2=Inc8,t0 // duplicate t0 in t2
  494. add t4=2*Inc8,t0 // duplicate t0 in t4
  495. mov t1=ar0 // ar.kr0
  496. mov t3=ar1 // ar.kr1
  497. mov t5=ar2;; // ar.kr2
  498. st8 [t0]=t1,3*Inc8
  499. st8 [t2]=t3,3*Inc8
  500. st8 [t4]=t5,3*Inc8;;
  501. mov t1=ar3 // ar.kr3
  502. mov t3=ar4 // ar.kr4
  503. mov t5=ar5;; // ar.kr5
  504. st8 [t0]=t1,3*Inc8
  505. st8 [t2]=t3,3*Inc8
  506. st8 [t4]=t5,13*Inc8;; // ar5->ar18
  507. mov t1=ar6 // ar.kr6
  508. mov t3=ar7;; // ar.kr7
  509. st8 [t0]=t1,10*Inc8
  510. st8 [t2]=t3,10*Inc8;;
  511. mov t1=ar16 // ar.rsc
  512. mov t3=ar17 // ar.bsp
  513. mov t5=ar18;; // ar.bspstore
  514. st8 [t0]=t1,3*Inc8
  515. st8 [t2]=t3,3*Inc8
  516. st8 [t4]=t5,3*Inc8;;
  517. mov t1=ar19;; // ar.rnat
  518. st8 [t0]=t1,Inc8*13 // increment by 13x8 bytes
  519. mov t1=ar32;; // ar.ccv
  520. st8 [t0]=t1,Inc8*4
  521. mov t1=ar36;; // ar.unat
  522. st8 [t0]=t1,Inc8*4
  523. mov t1=ar40;; // ar.fpsr
  524. st8 [t0]=t1,Inc8*4
  525. mov t1=ar44;; // ar.itc
  526. st8 [t0]=t1,160 // 160
  527. mov t1=ar64;; // ar.pfs
  528. st8 [t0]=t1,Inc8
  529. mov t1=ar65;; // ar.lc
  530. st8 [t0]=t1,Inc8
  531. mov t1=ar66;; // ar.ec
  532. st8 [t0]=t1
  533. adds t0=Inc8*62,t0 //padding
  534. // save RRs
  535. mov ar.lc=0x08-1
  536. movl t2=0x00;;
  537. cStRR::
  538. mov t1=rr[t2];;
  539. st8 [t0]=t1,Inc8
  540. add t2=1,t2
  541. br.cloop.dpnt cStRR
  542. ;;
  543. // align memory addresses to 16 bytes
  544. and t1=0x0f,t0;;
  545. cmp.ne.unc pt0,p0=t1,r0;;
  546. (pt0) add t0=Inc8,t0
  547. cSaveFRs::
  548. // just save FP for MCA restore only, "C" code will trash f6-f15
  549. // save ar.NaT
  550. mov t3=ar.unat;; // ar.unat
  551. stf.spill [t0]=f6,Inc16;;
  552. stf.spill [t0]=f7,Inc16;;
  553. stf.spill [t0]=f8,Inc16;;
  554. stf.spill [t0]=f9,Inc16;;
  555. stf.spill [t0]=f10,Inc16;;
  556. stf.spill [t0]=f11,Inc16;;
  557. stf.spill [t0]=f12,Inc16;;
  558. stf.spill [t0]=f13,Inc16;;
  559. stf.spill [t0]=f14,Inc16;;
  560. stf.spill [t0]=f15,Inc16;;
  561. mov t2=ar.unat;;
  562. st8 [t0]=t2,Inc8 // save User NaT bits for r16-r31
  563. mov ar.unat=t3 // restore original unat
  564. br.dpnt osMcaDoneDump
  565. ;;
  566. //EndStub//////////////////////////////////////////////////////////////////////
  567. //++
  568. // Name:
  569. // osMcaProcStateRestore()
  570. //
  571. // Stub Description:
  572. //
  573. // This is a stub to restore the saved processor state during MCHK
  574. //
  575. // On Entry:
  576. //
  577. // t0 = rPcrMcaStateDump.
  578. //
  579. // Return Value:
  580. //
  581. // None.
  582. //--
  583. osMcaProcStateRestore::
  584. // TF: ASSERT( t0 == rPcrMcaStateDump )
  585. restore_BRs::
  586. add t2=Inc8,t0 // duplicate t0 in t2
  587. add t4=2*Inc8,t0;; // duplicate t0 in t2
  588. ld8 t1=[t0],3*Inc8
  589. ld8 t3=[t2],3*Inc8
  590. ld8 t5=[t4],3*Inc8;;
  591. mov b0=t1
  592. mov b1=t3
  593. mov b2=t5;;
  594. ld8 t1=[t0],3*Inc8
  595. ld8 t3=[t2],3*Inc8
  596. ld8 t5=[t4],3*Inc8;;
  597. mov b3=t1
  598. mov b4=t3
  599. mov b5=t5;;
  600. ld8 t1=[t0],2*Inc8
  601. ld8 t3=[t2],2*Inc8;;
  602. mov b6=t1
  603. mov b7=t3;;
  604. restore_CRs::
  605. add t2=Inc8,t0 // duplicate t0 in t2
  606. add t4=2*Inc8,t0;; // duplicate t0 in t2
  607. ld8 t1=[t0],8*Inc8
  608. ld8 t3=[t2],3*Inc8
  609. ld8 t5=[t4],3*Inc8;; // 48 byte increments
  610. mov cr0=t1 // cr.dcr
  611. mov cr1=t3 // cr.itm
  612. mov cr2=t5;; // cr.iva
  613. ld8 t1=[t0],8*Inc8;; // 64 byte increments
  614. // mov cr8=t1 // cr.pta
  615. // if PSR.ic=1, reading interruption registers causes an illegal operation fault
  616. mov t1=psr;;
  617. tbit.nz.unc pt0,p0=t1,PSRic;; // PSI Valid Log bit pos. test
  618. (pt0) st8 [t0]=r0,9*8+160 // increment by 160 byte inc.
  619. (pt0) br.dpnt rSkipIntrRegs
  620. ;;
  621. add t2=Inc8,t0 // duplicate t0 in t2
  622. add t4=2*Inc8,t0;; // duplicate t0 in t2
  623. ld8 t1=[t0],3*Inc8
  624. ld8 t3=[t2],3*Inc8
  625. ld8 t5=[t4],3*Inc8;;
  626. mov cr16=t1 // cr.ipsr
  627. mov cr17=t3 // cr.isr is read only
  628. // mov cr18=t5;; // cr.ida
  629. ld8 t1=[t0],3*Inc8
  630. ld8 t3=[t2],3*Inc8
  631. ld8 t5=[t4],3*Inc8;;
  632. mov cr19=t1 // cr.iip
  633. mov cr20=t3 // cr.idtr
  634. mov cr21=t5;; // cr.iitr
  635. ld8 t1=[t0],3*Inc8
  636. ld8 t3=[t2],3*Inc8
  637. ld8 t5=[t4],3*Inc8;;
  638. mov cr22=t1 // cr.iipa
  639. mov cr23=t3 // cr.ifs
  640. mov cr24=t5 // cr.iim
  641. ld8 t1=[t0],160;; // 160 byte increment
  642. mov cr25=t1 // cr.iha
  643. rSkipIntrRegs::
  644. ld8 t1=[t0],168;; // another 168 byte inc.
  645. ld8 t1=[t0],40;; // 40 byte increment
  646. mov cr66=t1 // cr.lid
  647. ld8 t1=[t0],Inc8;;
  648. // mov cr71=t1 // cr.ivr is read only
  649. ld8 t1=[t0],24;; // 24 byte increment
  650. mov cr72=t1 // cr.tpr
  651. ld8 t1=[t0],168;; // 168 byte inc.
  652. // mov cr75=t1 // cr.eoi
  653. ld8 t1=[t0],Inc16;; // 16 byte inc.
  654. // mov cr96=t1 // cr.irr0 is read only
  655. ld8 t1=[t0],Inc16;; // 16 byte inc.
  656. // mov cr98=t1 // cr.irr1 is read only
  657. ld8 t1=[t0],Inc16;; // 16 byte inc
  658. // mov cr100=t1 // cr.irr2 is read only
  659. ld8 t1=[t0],Inc16;; // 16b inc.
  660. // mov cr102=t1 // cr.irr3 is read only
  661. ld8 t1=[t0],Inc16;; // 16 byte inc.
  662. // mov cr114=t1 // cr.itv
  663. ld8 t1=[t0],Inc8;;
  664. // mov cr116=t1 // cr.pmv
  665. ld8 t1=[t0],Inc8;;
  666. // mov cr117=t1 // cr.lrr0
  667. ld8 t1=[t0],Inc8;;
  668. // mov cr118=t1 // cr.lrr1
  669. ld8 t1=[t0],Inc8*10;;
  670. // mov cr119=t1 // cr.cmcv
  671. restore_ARs::
  672. add t2=Inc8,t0 // duplicate t0 in t2
  673. add t4=2*Inc8,t0;; // duplicate t0 in t2
  674. ld8 t1=[t0],3*Inc8
  675. ld8 t3=[t2],3*Inc8
  676. ld8 t5=[t4],3*Inc8;;
  677. mov ar0=t1 // ar.kro
  678. mov ar1=t3 // ar.kr1
  679. mov ar2=t5;; // ar.kr2
  680. ld8 t1=[t0],3*Inc8
  681. ld8 t3=[t2],3*Inc8
  682. ld8 t5=[t4],3*Inc8;;
  683. mov ar3=t1 // ar.kr3
  684. mov ar4=t3 // ar.kr4
  685. mov ar5=t5;; // ar.kr5
  686. ld8 t1=[t0],10*Inc8
  687. ld8 t3=[t2],10*Inc8
  688. ld8 t5=[t4],10*Inc8;;
  689. mov ar6=t1 // ar.kr6
  690. mov ar7=t3 // ar.kr7
  691. // mov ar8=t4 // ar.kr8
  692. ;;
  693. ld8 t1=[t0],3*Inc8
  694. ld8 t3=[t2],3*Inc8
  695. ld8 t5=[t4],3*Inc8;;
  696. // mov ar16=t1 // ar.rsc
  697. // mov ar17=t3 // ar.bsp is read only
  698. mov ar18=t5;; // ar.bspstore
  699. ld8 t1=[t0],Inc8*13;;
  700. mov ar19=t1 // ar.rnat
  701. ld8 t1=[t0],Inc8*4;;
  702. mov ar32=t1 // ar.ccv
  703. ld8 t1=[t0],Inc8*4;;
  704. mov ar36=t1 // ar.unat
  705. ld8 t1=[t0],Inc8*4;;
  706. mov ar40=t1 // ar.fpsr
  707. ld8 t1=[t0],160;; // 160
  708. // mov ar44=t1 // ar.itc
  709. ld8 t1=[t0],Inc8;;
  710. mov ar64=t1 // ar.pfs
  711. ld8 t1=[t0],Inc8;;
  712. mov ar65=t1 // ar.lc
  713. ld8 t1=[t0];;
  714. mov ar66=t1 // ar.ec
  715. adds t0=Inc8*62,t0;; // padding
  716. restore_RRs::
  717. mov t3=ar.lc
  718. mov ar.lc=0x08-1
  719. movl t2=0x00
  720. cStRRr::
  721. ld8 t1=[t0],Inc8;;
  722. // mov rr[t2]=t1 // what are its access previledges?
  723. add t2=1,t2
  724. br.cloop.dpnt cStRRr
  725. ;;
  726. mov ar.lc=t3
  727. // align memory addresses to 16 bytes
  728. and t1=0x0f,t0;;
  729. cmp.ne.unc pt0,p0=t1,r0;;
  730. (pt0) add t0=Inc8,t0;;
  731. // restore FP's which might be trashed by the "C" code
  732. mov t3=ar.unat
  733. add t1=16*10,t0;; // to get to NaT of GR 16-31
  734. ld8 t1=[t1];;
  735. mov ar.unat=t1;; // first restore NaT
  736. restore_FRs::
  737. ldf.fill f6=[t0],Inc16;;
  738. ldf.fill f7=[t0],Inc16;;
  739. ldf.fill f8=[t0],Inc16;;
  740. ldf.fill f9=[t0],Inc16;;
  741. ldf.fill f10=[t0],Inc16;;
  742. ldf.fill f11=[t0],Inc16;;
  743. ldf.fill f12=[t0],Inc16;;
  744. ldf.fill f13=[t0],Inc16;;
  745. ldf.fill f14=[t0],Inc16;;
  746. ldf.fill f15=[t0],Inc16;;
  747. mov ar.unat=t3 // restore original NaT
  748. br.dpnt osMcaDoneRestore
  749. ;;
  750. //EndStub//////////////////////////////////////////////////////////////////////
  751. //++
  752. // VOID
  753. // HalpAcquireMcaSpinLock (
  754. // IN PKSPIN_LOCK SpinLock
  755. // )
  756. //
  757. // Routine Description:
  758. //
  759. // This function acquires a MCA spin lock.
  760. // This function does not modify the interrupt state or the IRQL.
  761. //
  762. // N.B: This function does *NOT* replace KiAcquireSpinLock but
  763. // allows us to place it in a locked MCA specific section.
  764. //
  765. // Arguments:
  766. //
  767. // SpinLock (a0) - Supplies a pointer to a MCA spin lock.
  768. //
  769. // Return Value:
  770. //
  771. // None.
  772. //
  773. //--
  774. .align 16
  775. LEAF_ENTRY(HalpAcquireMcaSpinLock)
  776. #if !defined(NT_UP)
  777. ACQUIRE_SPINLOCK(a0,a0,Halpasl10)
  778. br.ret.dptk brp
  779. ;;
  780. #else
  781. LEAF_RETURN
  782. #endif // !defined(NT_UP)
  783. LEAF_EXIT(HalpAcquireMcaSpinLock)
  784. //EndProc//////////////////////////////////////////////////////////////////////
  785. //++
  786. // VOID
  787. // HalpReleaseMcaSpinLock (
  788. // IN PKSPIN_LOCK SpinLock
  789. // )
  790. //
  791. // Routine Description:
  792. //
  793. // This function release a MCA spin lock.
  794. // This function does not modify the interrupt state or the IRQL.
  795. //
  796. // N.B: This function does *NOT* replace KiReleaseSpinLock but
  797. // allows us to place it in a locked MCA specific section.
  798. //
  799. // Arguments:
  800. //
  801. // SpinLock (a0) - Supplies a pointer to a MCA spin lock.
  802. //
  803. // Return Value:
  804. //
  805. // None.
  806. //
  807. //--
  808. .align 16
  809. LEAF_ENTRY(HalpReleaseMcaSpinLock)
  810. #if !defined(NT_UP)
  811. st8.rel [a0] = zero // set spin lock not owned
  812. #endif
  813. LEAF_RETURN
  814. LEAF_EXIT(HalpReleaseMcaSpinLock)
  815. //EndProc//////////////////////////////////////////////////////////////////////
  816. //++
  817. // Name:
  818. // HalpMCAEnable()
  819. //
  820. // Routine Description:
  821. //
  822. // This procedure enables MCA resources that are not already enabled.
  823. //
  824. // Arguments:
  825. //
  826. // None
  827. //
  828. // Return value:
  829. //
  830. // None
  831. //
  832. //--
  833. .align 16
  834. .proc HalpMCAEnable
  835. HalpMCAEnable::
  836. NESTED_SETUP(0,2,0,0);;
  837. // nothing right now...
  838. NESTED_RETURN
  839. .endp HalpMCAEnable
  840. //EndProc//////////////////////////////////////////////////////////////////////