commsup.S 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. commsup.S
  5. Abstract:
  6. This module implements ARM processor architecture features not
  7. implementable in C that are common to all ARM architectures.
  8. Author:
  9. Chris Stevens 19-Mar-2014
  10. Environment:
  11. Kernel mode
  12. --*/
  13. ##
  14. ## ------------------------------------------------------------------ Includes
  15. ##
  16. #include <minoca/kernel/arm.inc>
  17. ##
  18. ## --------------------------------------------------------------- Definitions
  19. ##
  20. ##
  21. ## ---------------------------------------------------------------------- Code
  22. ##
  23. ASSEMBLY_FILE_HEADER
  24. .fpu vfpv3
  25. ##
  26. ## KERNEL_API
  27. ## BOOL
  28. ## ArDisableInterrupts (
  29. ## VOID
  30. ## )
  31. ##
  32. /*++
  33. Routine Description:
  34. This routine disables all interrupts on the current processor.
  35. Arguments:
  36. None.
  37. Return Value:
  38. TRUE if interrupts were previously enabled on the processor.
  39. FALSE if interrupts were not previously enabled on the processor.
  40. --*/
  41. PROTECTED_FUNCTION ArDisableInterrupts
  42. mrs %r1, CPSR @ Get the status register.
  43. cpsid i @ Disable interrupts.
  44. mov %r0, #0 @ Assume interrupts disabled.
  45. tst %r1, #PSR_FLAG_IRQ @ AND the interrupt flag.
  46. IT(eq) @ If the zero flag is set...
  47. moveq %r0, #1 @ Interrupts were enabled.
  48. bx %lr @ Return.
  49. END_FUNCTION ArDisableInterrupts
  50. ##
  51. ## KERNEL_API
  52. ## VOID
  53. ## ArEnableInterrupts (
  54. ## VOID
  55. ## )
  56. ##
  57. /*++
  58. Routine Description:
  59. This routine enables interrupts on the current processor.
  60. Arguments:
  61. None.
  62. Return Value:
  63. None.
  64. --*/
  65. PROTECTED_FUNCTION ArEnableInterrupts
  66. cpsie i @ Enable interrupts.
  67. bx %lr @
  68. END_FUNCTION ArEnableInterrupts
  69. ##
  70. ## KERNEL_API
  71. ## BOOL
  72. ## ArAreInterruptsEnabled (
  73. ## VOID
  74. ## )
  75. ##
  76. /*++
  77. Routine Description:
  78. This routine determines whether or not interrupts are currently enabled
  79. on the processor.
  80. Arguments:
  81. None.
  82. Return Value:
  83. TRUE if interrupts are enabled in the processor.
  84. FALSE if interrupts are globally disabled.
  85. --*/
  86. PROTECTED_FUNCTION ArAreInterruptsEnabled
  87. mrs %r1, CPSR @ Get the status register.
  88. mov %r0, #0 @ Assume interrupts disabled.
  89. tst %r1, #PSR_FLAG_IRQ @ AND the interrupt flag.
  90. IT(eq) @ If the zero flag is set...
  91. moveq %r0, #1 @ Interrupts were enabled.
  92. bx %lr @ Return.
  93. END_FUNCTION ArAreInterruptsEnabled
  94. ##
  95. ## ULONG
  96. ## ArGetProcessorFlags (
  97. ## VOID
  98. ## )
  99. ##
  100. /*++
  101. Routine Description:
  102. This routine gets the current processor's flags register.
  103. Arguments:
  104. None.
  105. Return Value:
  106. Returns the current flags.
  107. --*/
  108. FUNCTION ArGetProcessorFlags
  109. mrs %r0, CPSR @ Get the status register.
  110. bx %lr @
  111. END_FUNCTION ArGetProcessorFlags
  112. ##
  113. ## ULONG
  114. ## ArGetCacheTypeRegister (
  115. ## VOID
  116. ## )
  117. ##
  118. /*++
  119. Routine Description:
  120. This routine retrives the Cache Type Register (CTR) from the system
  121. coprocessor.
  122. Arguments:
  123. None.
  124. Return Value:
  125. Returns the value of the CTR.
  126. --*/
  127. FUNCTION ArGetCacheTypeRegister
  128. mrc p15, 0, %r0, %cr0, %cr0, 1 @ Read the CTR.
  129. bx %lr @
  130. END_FUNCTION ArGetCacheTypeRegister
  131. ##
  132. ## VOID
  133. ## ArInvalidateInstructionCache (
  134. ## VOID
  135. ## )
  136. ##
  137. /*++
  138. Routine Description:
  139. This routine invalidate the processor's instruction only cache, indicating
  140. that a page containing code has changed.
  141. Arguments:
  142. None.
  143. Return Value:
  144. None.
  145. --*/
  146. FUNCTION ArInvalidateInstructionCache
  147. DSB
  148. mcr p15, 0, %r0, c7, c5, 0 @ ICIALLU, Invalidate I-Cache.
  149. DSB @ Make instructions finish.
  150. ISB @ Prevent speculative fetching.
  151. bx %lr @ Return
  152. END_FUNCTION ArInvalidateInstructionCache
  153. ##
  154. ## VOID
  155. ## ArInvalidateTlbEntry (
  156. ## PVOID Address
  157. ## )
  158. ##
  159. /*++
  160. Routine Description:
  161. This routine invalidates one TLB entry corresponding to the given virtual
  162. address.
  163. Arguments:
  164. Address - Supplies the virtual address whose associated TLB entry will be
  165. invalidated.
  166. Return Value:
  167. None.
  168. --*/
  169. FUNCTION ArInvalidateTlbEntry
  170. DSB @ Ensure changes are visible.
  171. mcr p15, 0, %r0, %cr8, %cr7, 1 @ Write to TLBIMVA.
  172. BPIALL @ Write to BPIALL (branch pred).
  173. DSB @ Data synchronization barrier.
  174. ISB @ Instruction sync barrier.
  175. bx %lr @
  176. END_FUNCTION ArInvalidateTlbEntry
  177. ##
  178. ## VOID
  179. ## ArInvalidateEntireTlb (
  180. ## VOID
  181. ## )
  182. ##
  183. /*++
  184. Routine Description:
  185. This routine invalidates the entire TLB.
  186. Arguments:
  187. None.
  188. Return Value:
  189. None.
  190. --*/
  191. FUNCTION ArInvalidateEntireTlb
  192. DSB @ Ensure changes are visible.
  193. mcr p15, 0, %r0, c8, c7, 0 @ TLBIALL (invalidate TLB).
  194. BPIALL @ Write to BPIALL (branch pred).
  195. DSB @ Data synchronization barrier.
  196. ISB @ Instruction sync barrier.
  197. bx %lr @
  198. END_FUNCTION ArInvalidateEntireTlb
  199. ##
  200. ## ULONG
  201. ## ArLockTlbEntry (
  202. ## ULONG TlbEntry,
  203. ## PVOID VirtualAddress,
  204. ## ULONG NextTlbEntry
  205. ## )
  206. ##
  207. /*++
  208. Routine Description:
  209. This routine locks a translation in the TLB. This translation will stick
  210. even across total TLB invalidates.
  211. Arguments:
  212. TlbEntry - Supplies the base and victim number of the TLB entry to lock.
  213. VirtualAddress - Supplies the virtual address that should be locked in the
  214. TLB. The association to physical address will be created by touching
  215. that address, so the address had better be mapped.
  216. NextTlbEntry - Supplies the base and victim number to set after locking the
  217. entry.
  218. Return Value:
  219. Returns the value of the lockdown register after the TLB miss was forced.
  220. The lowest bit of this value should be set. If it is not, this indicates
  221. that TLB lockdown is not supported.
  222. --*/
  223. FUNCTION ArLockTlbEntry
  224. orr %r0, %r0, #1 @ Set lock flag.
  225. mcr p15, 0, %r1, %cr8, %cr7, 1 @ Invalidate the TLB entry.
  226. mcr p15, 0, %r0, %cr10, %cr0, 0 @ Write lockdown register.
  227. mcr p15, 0, %r1, %cr10, %cr1, 0 @ Prefetch data TLB.
  228. ldr %r3, [%r1] @ Also do standard load.
  229. mrc p15, 0, %r0, %cr10, %cr0, 0 @ Read the lockdown register.
  230. bic %r2, %r2, #1 @ Clear lock flag.
  231. mcr p15, 0, %r2, %cr10, %cr0, 0 @ Write lockdown register.
  232. DSB @ Make instructions finish.
  233. ISB @ Prevent speculative fetching.
  234. bx %lr @ Return.
  235. END_FUNCTION ArLockTlbEntry
  236. ##
  237. ## VOID
  238. ## ArSerializeExecution (
  239. ## VOID
  240. ## )
  241. ##
  242. /*++
  243. Routine Description:
  244. This routine acts a serializing instruction, preventing the processor
  245. from speculatively executing beyond this point.
  246. Arguments:
  247. None.
  248. Return Value:
  249. None.
  250. --*/
  251. FUNCTION ArSerializeExecution
  252. DSB
  253. ISB
  254. bx %lr
  255. END_FUNCTION ArSerializeExecution
  256. ##
  257. ## PVOID
  258. ## ArGetDataFaultingAddress (
  259. ## VOID
  260. ## )
  261. ##
  262. /*++
  263. Routine Description:
  264. This routine determines which address caused a data abort.
  265. Arguments:
  266. None.
  267. Return Value:
  268. Returns the faulting address.
  269. --*/
  270. FUNCTION ArGetDataFaultingAddress
  271. mrc p15, 0, %r0, %cr6, %cr0, 0 @ Get the combined/data FAR.
  272. bx %lr @
  273. END_FUNCTION ArGetDataFaultingAddress
  274. ##
  275. ## VOID
  276. ## ArSetDataFaultingAddress (
  277. ## PVOID Value
  278. ## )
  279. ##
  280. /*++
  281. Routine Description:
  282. This routine sets the data faulting address register (DFAR).
  283. Arguments:
  284. Value - Supplies the value to set.
  285. Return Value:
  286. None.
  287. --*/
  288. FUNCTION ArSetDataFaultingAddress
  289. mcr p15, 0, %r0, %cr6, %cr0, 0
  290. bx %lr
  291. END_FUNCTION ArSetDataFaultingAddress
  292. ##
  293. ## PVOID
  294. ## ArGetInstructionFaultingAddress (
  295. ## VOID
  296. ## )
  297. ##
  298. /*++
  299. Routine Description:
  300. This routine determines which address caused a prefetch abort.
  301. Arguments:
  302. None.
  303. Return Value:
  304. Returns the faulting address.
  305. --*/
  306. FUNCTION ArGetInstructionFaultingAddress
  307. mrc p15, 0, %r0, %cr6, %cr0, 2 @ Get the IFAR.
  308. bx %lr @
  309. END_FUNCTION ArGetInstructionFaultingAddress
  310. ##
  311. ## VOID
  312. ## ArSetInstructionFaultingAddress (
  313. ## PVOID Value
  314. ## )
  315. ##
  316. /*++
  317. Routine Description:
  318. This routine sets the instruction faulting address register (IFAR).
  319. Arguments:
  320. Value - Supplies the value to set.
  321. Return Value:
  322. None.
  323. --*/
  324. FUNCTION ArSetInstructionFaultingAddress
  325. mcr p15, 0, %r0, %cr6, %cr0, 2
  326. bx %lr
  327. END_FUNCTION ArSetInstructionFaultingAddress
  328. ##
  329. ## ULONG
  330. ## ArGetDataFaultStatus (
  331. ## VOID
  332. ## )
  333. ##
  334. /*++
  335. Routine Description:
  336. This routine determines the reason for the fault by reading the DFSR
  337. register.
  338. Arguments:
  339. None.
  340. Return Value:
  341. Returns the contents of the Data Fault Status Register.
  342. --*/
  343. FUNCTION ArGetDataFaultStatus
  344. mrc p15, 0, %r0, %cr5, %cr0, 0 @ Get the DFSR.
  345. bx %lr @
  346. END_FUNCTION ArGetDataFaultStatus
  347. ##
  348. ## VOID
  349. ## ArSetDataFaultStatus (
  350. ## ULONG Value
  351. ## )
  352. ##
  353. /*++
  354. Routine Description:
  355. This routine sets the data fault status register (DFSR).
  356. Arguments:
  357. Value - Supplies the value to set.
  358. Return Value:
  359. None.
  360. --*/
  361. FUNCTION ArSetDataFaultStatus
  362. mcr p15, 0, %r0, %cr5, %cr0, 0
  363. bx %lr
  364. END_FUNCTION ArSetDataFaultStatus
  365. ##
  366. ## ULONG
  367. ## ArGetInstructionFaultStatus (
  368. ## VOID
  369. ## )
  370. ##
  371. /*++
  372. Routine Description:
  373. This routine determines the reason for the prefetch abort by reading the
  374. IFAR register.
  375. Arguments:
  376. None.
  377. Return Value:
  378. Returns the contents of the Instruction Fault Status Register.
  379. --*/
  380. FUNCTION ArGetInstructionFaultStatus
  381. mrc p15, 0, %r0, %cr5, %cr0, 1 @ Get the IFSR.
  382. bx %lr @
  383. END_FUNCTION ArGetInstructionFaultStatus
  384. ##
  385. ## VOID
  386. ## ArSetInstructionFaultStatus (
  387. ## ULONG Value
  388. ## )
  389. ##
  390. /*++
  391. Routine Description:
  392. This routine sets the instruction fault status register (IFSR).
  393. Arguments:
  394. Value - Supplies the value to set.
  395. Return Value:
  396. None.
  397. --*/
  398. FUNCTION ArSetInstructionFaultStatus
  399. mcr p15, 0, %r0, %cr5, %cr0, 1
  400. bx %lr
  401. END_FUNCTION ArSetInstructionFaultStatus
  402. ##
  403. ## VOID
  404. ## ArProcessorYield (
  405. ## VOID
  406. ## )
  407. ##
  408. /*++
  409. Routine Description:
  410. This routine executes a short processor yield in hardware.
  411. Arguments:
  412. None.
  413. Return Value:
  414. None.
  415. --*/
  416. FUNCTION ArProcessorYield
  417. yield
  418. bx %lr
  419. END_FUNCTION ArProcessorYield
  420. ##
  421. ## KERNEL_API
  422. ## VOID
  423. ## ArWaitForInterrupt (
  424. ## VOID
  425. ## )
  426. ##
  427. /*++
  428. Routine Description:
  429. This routine halts the processor until the next interrupt comes in. This
  430. routine should be called with interrupts disabled, and will return with
  431. interrupts enabled.
  432. Arguments:
  433. None.
  434. Return Value:
  435. None.
  436. --*/
  437. PROTECTED_FUNCTION ArWaitForInterrupt
  438. DSB @ Ensure everything is done.
  439. wfi @ Wait for interrupt.
  440. cpsie if @ Enable interrupts.
  441. bx %lr
  442. END_FUNCTION ArWaitForInterrupt
  443. ##
  444. ## VOID
  445. ## ArCpuid (
  446. ## PARM_CPUID Features
  447. ## )
  448. ##
  449. /*++
  450. Routine Description:
  451. This routine returns the set of processor features present on the current
  452. processor.
  453. Arguments:
  454. Features - Supplies a pointer where the processor feature register values
  455. will be returned.
  456. Return Value:
  457. None.
  458. --*/
  459. FUNCTION ArCpuid
  460. mrc p15, 0, %r1, c0, c1, 0 @ Get ID_PFR0.
  461. str %r1, [%r0], #4 @ Save it.
  462. mrc p15, 0, %r1, c0, c1, 1 @ Get ID_PFR1.
  463. str %r1, [%r0], #4 @ Save it.
  464. mrc p15, 0, %r1, c0, c1, 2 @ Get ID_DFR0.
  465. str %r1, [%r0], #4 @ Save it.
  466. mrc p15, 0, %r1, c0, c1, 3 @ Get ID_AFR0.
  467. str %r1, [%r0], #4 @ Save it.
  468. mrc p15, 0, %r1, c0, c1, 4 @ Get ID_MMFR0.
  469. str %r1, [%r0], #4 @ Save it.
  470. mrc p15, 0, %r1, c0, c1, 5 @ Get ID_MMFR1.
  471. str %r1, [%r0], #4 @ Save it.
  472. mrc p15, 0, %r1, c0, c1, 6 @ Get ID_MMFR2.
  473. str %r1, [%r0], #4 @ Save it.
  474. mrc p15, 0, %r1, c0, c1, 7 @ Get ID_MMFR3.
  475. str %r1, [%r0], #4 @ Save it.
  476. mrc p15, 0, %r1, c0, c2, 0 @ Get ID_IDAR0.
  477. str %r1, [%r0], #4 @ Save it.
  478. mrc p15, 0, %r1, c0, c2, 1 @ Get ID_IDAR1.
  479. str %r1, [%r0], #4 @ Save it.
  480. mrc p15, 0, %r1, c0, c2, 2 @ Get ID_IDAR2.
  481. str %r1, [%r0], #4 @ Save it.
  482. mrc p15, 0, %r1, c0, c2, 3 @ Get ID_IDAR3.
  483. str %r1, [%r0], #4 @ Save it.
  484. mrc p15, 0, %r1, c0, c2, 4 @ Get ID_IDAR4.
  485. str %r1, [%r0], #4 @ Save it.
  486. mrc p15, 0, %r1, c0, c2, 5 @ Get ID_IDAR5.
  487. str %r1, [%r0], #4 @ Save it.
  488. bx %lr @ Return!
  489. END_FUNCTION ArCpuid
  490. ##
  491. ## ULONG
  492. ## ArGetSystemControlRegister (
  493. ## VOID
  494. ## )
  495. ##
  496. /*++
  497. Routine Description:
  498. This routine returns the MMU system control register (SCTLR).
  499. Arguments:
  500. None.
  501. Return Value:
  502. Returns the current SCTLR value.
  503. --*/
  504. FUNCTION ArGetSystemControlRegister
  505. mrc p15, 0, %r0, %cr1, %cr0, 0 @ Get the SCTLR.
  506. bx %lr @ Return.
  507. END_FUNCTION ArGetSystemControlRegister
  508. ##
  509. ## VOID
  510. ## ArSetSystemControlRegister (
  511. ## ULONG NewValue
  512. ## )
  513. ##
  514. /*++
  515. Routine Description:
  516. This routine sets the MMU system control register (SCTLR).
  517. Arguments:
  518. NewValue - Supplies the value to set as the new MMU SCTLR.
  519. Return Value:
  520. None.
  521. --*/
  522. FUNCTION ArSetSystemControlRegister
  523. mcr p15, 0, %r0, %cr1, %cr0, 0 @ Set the SCTLR.
  524. bx %lr @ Return.
  525. END_FUNCTION ArSetSystemControlRegister
  526. ##
  527. ## ULONG
  528. ## ArGetAuxiliaryControlRegister (
  529. ## VOID
  530. ## )
  531. ##
  532. /*++
  533. Routine Description:
  534. This routine returns the auxiliary system control register (ACTLR).
  535. Arguments:
  536. None.
  537. Return Value:
  538. Returns the current value.
  539. --*/
  540. FUNCTION ArGetAuxiliaryControlRegister
  541. mrc p15, 0, %r0, %cr1, %cr0, 1
  542. bx %lr
  543. END_FUNCTION ArGetAuxiliaryControlRegister
  544. ##
  545. ## VOID
  546. ## ArSetAuxiliaryControlRegister (
  547. ## ULONG NewValue
  548. ## )
  549. ##
  550. /*++
  551. Routine Description:
  552. This routine sets the auxiliary system control register (ACTLR).
  553. Arguments:
  554. NewValue - Supplies the value to set.
  555. Return Value:
  556. None.
  557. --*/
  558. FUNCTION ArSetAuxiliaryControlRegister
  559. mcr p15, 0, %r0, %cr1, %cr0, 1
  560. bx %lr
  561. END_FUNCTION ArSetAuxiliaryControlRegister
  562. ##
  563. ## PVOID
  564. ## ArGetVectorBaseAddress (
  565. ## VOID
  566. ## )
  567. ##
  568. /*++
  569. Routine Description:
  570. This routine gets the vector base address register (VBAR) which determines
  571. where the ARM exception vector table starts.
  572. Arguments:
  573. None.
  574. Return Value:
  575. Returns the current VBAR.
  576. --*/
  577. FUNCTION ArGetVectorBaseAddress
  578. mrc p15, 0, %r0, c12, c0, 0
  579. bx %lr
  580. END_FUNCTION ArGetVectorBaseAddress
  581. ##
  582. ## VOID
  583. ## ArSetVectorBaseAddress (
  584. ## PVOID VectorBaseAddress
  585. ## )
  586. ##
  587. /*++
  588. Routine Description:
  589. This routine sets the vector base address register (VBAR) which determines
  590. where the ARM exception vector table starts.
  591. Arguments:
  592. VectorBaseAddress - Supplies a pointer to the ARM exception vector base
  593. address. This value must be 32-byte aligned.
  594. Return Value:
  595. None.
  596. --*/
  597. FUNCTION ArSetVectorBaseAddress
  598. mcr p15, 0, %r0, c12, c0, 0 @ Set VBAR.
  599. bx %lr @ Return.
  600. END_FUNCTION ArSetVectorBaseAddress
  601. ##
  602. ## PVOID
  603. ## ArGetProcessorBlockRegister (
  604. ## VOID
  605. ## )
  606. ##
  607. /*++
  608. Routine Description:
  609. This routine gets the register used to store a pointer to the processor
  610. block (TPIDRPRW in the ARMARM; Thread and Process ID Registers in the
  611. ARM1176 TRM).
  612. Arguments:
  613. None.
  614. Return Value:
  615. Returns a pointer to the processor block.
  616. --*/
  617. FUNCTION ArGetProcessorBlockRegister
  618. mrc p15, 0, %r0, c13, c0, 4 @ Get TPIDRPRW.
  619. bx %lr @ Return.
  620. END_FUNCTION ArGetProcessorBlockRegister
  621. ##
  622. ## PVOID
  623. ## ArGetProcessorBlockRegisterForDebugger (
  624. ## VOID
  625. ## )
  626. ##
  627. /*++
  628. Routine Description:
  629. This routine gets the register used to store a pointer to the processor
  630. block (TPIDRPRW in the ARMARM; Thread and Process ID Registers in the
  631. ARM1176 TRM). This routine is called from inside the debugger.
  632. Arguments:
  633. None.
  634. Return Value:
  635. Returns a pointer to the processor block.
  636. --*/
  637. FUNCTION ArGetProcessorBlockRegisterForDebugger
  638. mrc p15, 0, %r0, c13, c0, 4 @ Get TPIDRPRW.
  639. bx %lr @ Return.
  640. END_FUNCTION ArGetProcessorBlockRegisterForDebugger
  641. ##
  642. ## VOID
  643. ## ArSetProcessorBlockRegister (
  644. ## PVOID ProcessorBlockRegisterValue
  645. ## )
  646. ##
  647. /*++
  648. Routine Description:
  649. This routine sets the register used to store a pointer to the processor
  650. block (TPIDRPRW in the ARMARM; Thread and Process ID Registers in the
  651. ARM1176 TRM).
  652. Arguments:
  653. ProcessorBlockRegisterValue - Supplies the value to assign to the register
  654. used to store the processor block.
  655. Return Value:
  656. None.
  657. --*/
  658. FUNCTION ArSetProcessorBlockRegister
  659. mcr p15, 0, %r0, c13, c0, 4 @ Set TPIDRPRW.
  660. bx %lr @ Return.
  661. END_FUNCTION ArSetProcessorBlockRegister
  662. ##
  663. ## UINTN
  664. ## ArDereferenceProcessorBlock (
  665. ## UINTN Offset
  666. ## )
  667. ##
  668. /*++
  669. Routine Description:
  670. This routine performs a native integer read of the processor block plus
  671. a given offset. The C equivalent of this would be
  672. *((PUINTN)(ProcessorBlock + Offset)).
  673. Arguments:
  674. Offset - Supplies the offset into the processor block to read.
  675. Return Value:
  676. Returns the native integer read at the given address.
  677. --*/
  678. FUNCTION ArDereferenceProcessorBlock
  679. mrs %r1, CPSR @ Get the original status register.
  680. cpsid i @ Disable interrupts.
  681. mrc p15, 0, %r2, c13, c0, 4 @ Get TPIDRPRW.
  682. ldr %r0, [%r2, %r0] @ Read at offset.
  683. msr CPSR, %r1 @ Restore interrupts.
  684. bx %lr @ Return.
  685. END_FUNCTION ArDereferenceProcessorBlock
  686. ##
  687. ## ULONG
  688. ## ArGetTranslationTableBaseRegister0 (
  689. ## VOID
  690. ## )
  691. ##
  692. /*++
  693. Routine Description:
  694. This routine gets the translation table base register 0 (TTBR0), used as
  695. the base for all virtual to physical memory lookups.
  696. Arguments:
  697. None.
  698. Return Value:
  699. Returns the contents of TTBR0.
  700. --*/
  701. FUNCTION ArGetTranslationTableBaseRegister0
  702. mrc p15, 0, %r0, c2, c0, 0 @ Get TTBR0.
  703. bx %lr @ Return.
  704. END_FUNCTION ArGetTranslationTableBaseRegister0
  705. ##
  706. ## VOID
  707. ## ArSetTranslationTableBaseRegister0 (
  708. ## ULONG Value
  709. ## )
  710. ##
  711. /*++
  712. Routine Description:
  713. This routine sets the translation table base register 0 (TTBR0).
  714. Arguments:
  715. Value - Supplies the value to write.
  716. Return Value:
  717. None.
  718. --*/
  719. FUNCTION ArSetTranslationTableBaseRegister0
  720. mcr p15, 0, %r0, c2, c0, 0
  721. bx %lr
  722. END_FUNCTION ArSetTranslationTableBaseRegister0
  723. ##
  724. ## ULONG
  725. ## ArGetTranslationTableBaseRegister1 (
  726. ## VOID
  727. ## )
  728. ##
  729. /*++
  730. Routine Description:
  731. This routine gets the translation table base register 1 (TTBR1).
  732. Arguments:
  733. None.
  734. Return Value:
  735. Returns the contents of TTBR1.
  736. --*/
  737. FUNCTION ArGetTranslationTableBaseRegister1
  738. mrc p15, 0, %r0, c2, c0, 1
  739. bx %lr
  740. END_FUNCTION ArGetTranslationTableBaseRegister1
  741. ##
  742. ## VOID
  743. ## ArSetTranslationTableBaseRegister1 (
  744. ## ULONG Value
  745. ## )
  746. ##
  747. /*++
  748. Routine Description:
  749. This routine sets the translation table base register 1 (TTBR1).
  750. Arguments:
  751. Value - Supplies the value to write.
  752. Return Value:
  753. None.
  754. --*/
  755. FUNCTION ArSetTranslationTableBaseRegister1
  756. mcr p15, 0, %r0, c2, c0, 1
  757. bx %lr
  758. END_FUNCTION ArSetTranslationTableBaseRegister1
  759. ##
  760. ## ULONG
  761. ## ArGetPrimaryRegionRemapRegister (
  762. ## VOID
  763. ## )
  764. ##
  765. /*++
  766. Routine Description:
  767. This routine gets the Primary Region Remap Register (PRRR).
  768. Arguments:
  769. None.
  770. Return Value:
  771. Returns the contents of the register.
  772. --*/
  773. FUNCTION ArGetPrimaryRegionRemapRegister
  774. mrc p15, 0, %r0, c10, c2, 0
  775. bx %lr
  776. END_FUNCTION ArGetPrimaryRegionRemapRegister
  777. ##
  778. ## VOID
  779. ## ArSetPrimaryRegionRemapRegister (
  780. ## ULONG Value
  781. ## )
  782. ##
  783. /*++
  784. Routine Description:
  785. This routine sets the PRRR.
  786. Arguments:
  787. Value - Supplies the value to write.
  788. Return Value:
  789. None.
  790. --*/
  791. FUNCTION ArSetPrimaryRegionRemapRegister
  792. mcr p15, 0, %r0, c10, c2, 0
  793. bx %lr
  794. END_FUNCTION ArSetPrimaryRegionRemapRegister
  795. ##
  796. ## ULONG
  797. ## ArGetNormalMemoryRemapRegister (
  798. ## VOID
  799. ## )
  800. ##
  801. /*++
  802. Routine Description:
  803. This routine gets the Normal Memory Remap Register (NMRR).
  804. Arguments:
  805. None.
  806. Return Value:
  807. Returns the contents of the register.
  808. --*/
  809. FUNCTION ArGetNormalMemoryRemapRegister
  810. mrc p15, 0, %r0, c10, c2, 1
  811. bx %lr
  812. END_FUNCTION ArGetNormalMemoryRemapRegister
  813. ##
  814. ## VOID
  815. ## ArSetNormalMemoryRemapRegister (
  816. ## ULONG Value
  817. ## )
  818. ##
  819. /*++
  820. Routine Description:
  821. This routine sets the NMRR.
  822. Arguments:
  823. Value - Supplies the value to write.
  824. Return Value:
  825. None.
  826. --*/
  827. FUNCTION ArSetNormalMemoryRemapRegister
  828. mcr p15, 0, %r0, c10, c2, 1
  829. bx %lr
  830. END_FUNCTION ArSetNormalMemoryRemapRegister
  831. ##
  832. ## ULONG
  833. ## ArGetPhysicalAddressRegister (
  834. ## VOID
  835. ## )
  836. ##
  837. /*++
  838. Routine Description:
  839. This routine gets the Physical Address Register (PAR).
  840. Arguments:
  841. None.
  842. Return Value:
  843. Returns the contents of the register.
  844. --*/
  845. FUNCTION ArGetPhysicalAddressRegister
  846. mrc p15, 0, %r0, c7, c4, 0
  847. bx %lr
  848. END_FUNCTION ArGetPhysicalAddressRegister
  849. ##
  850. ## VOID
  851. ## ArSetPhysicalAddressRegister (
  852. ## ULONG Value
  853. ## )
  854. ##
  855. /*++
  856. Routine Description:
  857. This routine sets the Physical Address Register (PAR).
  858. Arguments:
  859. Value - Supplies the value to write.
  860. Return Value:
  861. None.
  862. --*/
  863. FUNCTION ArSetPhysicalAddressRegister
  864. mcr p15, 0, %r0, c7, c4, 0
  865. bx %lr
  866. END_FUNCTION ArSetPhysicalAddressRegister
  867. ##
  868. ## VOID
  869. ## ArSetPrivilegedReadTranslateRegister (
  870. ## ULONG Value
  871. ## )
  872. ##
  873. /*++
  874. Routine Description:
  875. This routine sets the Privileged Read address translation command register.
  876. Arguments:
  877. Value - Supplies the value to write.
  878. Return Value:
  879. None.
  880. --*/
  881. FUNCTION ArSetPrivilegedReadTranslateRegister
  882. mcr p15, 0, %r0, c7, c8, 0
  883. bx %lr
  884. END_FUNCTION ArSetPrivilegedReadTranslateRegister
  885. ##
  886. ## VOID
  887. ## ArSetPrivilegedWriteTranslateRegister (
  888. ## ULONG Value
  889. ## )
  890. ##
  891. /*++
  892. Routine Description:
  893. This routine sets the Privileged Write address translation command register.
  894. Arguments:
  895. Value - Supplies the value to write.
  896. Return Value:
  897. None.
  898. --*/
  899. FUNCTION ArSetPrivilegedWriteTranslateRegister
  900. mcr p15, 0, %r0, c7, c8, 1
  901. bx %lr
  902. END_FUNCTION ArSetPrivilegedWriteTranslateRegister
  903. ##
  904. ## VOID
  905. ## ArSetUnprivilegedReadTranslateRegister (
  906. ## ULONG Value
  907. ## )
  908. ##
  909. /*++
  910. Routine Description:
  911. This routine sets the Unrivileged Read address translation command register.
  912. Arguments:
  913. Value - Supplies the value to write.
  914. Return Value:
  915. None.
  916. --*/
  917. FUNCTION ArSetUnprivilegedReadTranslateRegister
  918. mcr p15, 0, %r0, c7, c8, 2
  919. bx %lr
  920. END_FUNCTION ArSetUnprivilegedReadTranslateRegister
  921. ##
  922. ## VOID
  923. ## ArSetUnprivilegedWriteTranslateRegister (
  924. ## ULONG Value
  925. ## )
  926. ##
  927. /*++
  928. Routine Description:
  929. This routine sets the Unprivileged Write address translation command
  930. register.
  931. Arguments:
  932. Value - Supplies the value to write.
  933. Return Value:
  934. None.
  935. --*/
  936. FUNCTION ArSetUnprivilegedWriteTranslateRegister
  937. mcr p15, 0, %r0, c7, c8, 3
  938. bx %lr
  939. END_FUNCTION ArSetUnprivilegedWriteTranslateRegister
  940. ##
  941. ## ULONG
  942. ## ArTranslateVirtualToPhysical (
  943. ## PVOID VirtualAddress
  944. ## )
  945. ##
  946. /*++
  947. Routine Description:
  948. This routine translates a virtual address to its corresponding physical
  949. address by using the current translation tables.
  950. Arguments:
  951. VirtualAddress - Supplies the virtual address to translate.
  952. Return Value:
  953. Returns the physical address that the virtual address corresponds to
  954. (with some bits at the bottom relating to the cache type).
  955. --*/
  956. FUNCTION ArTranslateVirtualToPhysical
  957. mrs %r1, CPSR @ Get the status register.
  958. orr %r2, %r1, #PSR_FLAG_IRQ @ Turn on the interrupt mask bit.
  959. msr CPSR_cxsf, %r2 @ Write the status register.
  960. mcr p15, 0, %r0, c7, c8, 0 @ Write VA into V2PCWPR
  961. mrc p15, 0, %r0, c7, c4, 0 @ Read PAR.
  962. msr CPSR_cxsf, %r1 @ Restore interrupts.
  963. bx %lr @ Return.
  964. END_FUNCTION ArTranslateVirtualToPhysical
  965. ##
  966. ## VOID
  967. ## ArSetThreadPointerUserReadOnly (
  968. ## PVOID NewPointer
  969. ## )
  970. ##
  971. /*++
  972. Routine Description:
  973. This routine sets the TPIDRURO user-mode-read-only thread pointer register.
  974. Arguments:
  975. NewPointer - Supplies the value to write.
  976. Return Value:
  977. None.
  978. --*/
  979. FUNCTION ArSetThreadPointerUserReadOnly
  980. mcr p15, 0, %r0, c13, c0, 3 @ Set the TPIDRURO register.
  981. bx %lr
  982. END_FUNCTION ArSetThreadPointerUserReadOnly
  983. ##
  984. ## ULONG
  985. ## ArGetThreadPointerUser (
  986. ## VOID
  987. ## )
  988. ##
  989. /*++
  990. Routine Description:
  991. This routine sets the TPIDRURW user-mode thread pointer register.
  992. Arguments:
  993. None.
  994. Return Value:
  995. Returns the current value of the TPIDRURW.
  996. --*/
  997. FUNCTION ArGetThreadPointerUser
  998. mrc p15, 0, %r0, c13, c0, 2 @ Get the TPIDRURW register.
  999. bx %lr
  1000. END_FUNCTION ArGetThreadPointerUser
  1001. ##
  1002. ## VOID
  1003. ## ArSwitchTtbr0 (
  1004. ## ULONG NewValue
  1005. ## )
  1006. ##
  1007. /*++
  1008. Routine Description:
  1009. This routine performs the proper sequence for changing contexts in TTBR0,
  1010. including the necessary invalidates and barriers.
  1011. Arguments:
  1012. NewValue - Supplies the new value to write.
  1013. Return Value:
  1014. None.
  1015. --*/
  1016. FUNCTION ArSwitchTtbr0
  1017. mcr p15, 0, %r0, c2, c0, 0 @ Set TTBR0.
  1018. mov %r0, #0 @ Get a zero register.
  1019. DSB @ Ensure everything finished.
  1020. mcr p15, 0, %r0, c8, c7, 0 @ TLBIALL, Invalidate entire TLB.
  1021. mcr p15, 0, %r0, c7, c5, 0 @ ICIALLU, Invalidate I-Cache + BTB.
  1022. DSB @ Ensure those operations finished.
  1023. ISB @ Instruction synchronization.
  1024. bx %lr @ Return.
  1025. END_FUNCTION ArSwitchTtbr0
  1026. ##
  1027. ## UINTN
  1028. ## ArSaveProcessorContext (
  1029. ## PPROCESSOR_CONTEXT Context
  1030. ## )
  1031. ##
  1032. /*++
  1033. Routine Description:
  1034. This routine saves the current processor context, including the
  1035. non-volatile general registers and the system level control registers. This
  1036. function appears to return twice, once when the context is saved and then
  1037. again when the context is restored. Because the stack pointer is restored,
  1038. the caller of this function may not return without either abandoning the
  1039. context or calling restore. Returning and then calling restore would almost
  1040. certainly result in stack corruption.
  1041. Arguments:
  1042. Context - Supplies a pointer to the context area to save into.
  1043. Return Value:
  1044. Returns 0 after the context was successfully saved (first time).
  1045. Returns the value in the context return address register when the restore
  1046. function is called (the second time). By default this value is 1, though it
  1047. can be manipulated after the initial save is complete.
  1048. --*/
  1049. FUNCTION ArSaveProcessorContext
  1050. stmia %r0!, {%lr} @ Save PC (return address).
  1051. mov %r1, #1 @ "Save" 1 to R0.
  1052. stmia %r0!, {%r1} @
  1053. mov %r1, #0 @ "Save" 0 to R1, R2, and R3.
  1054. stmia %r0!, {%r1} @
  1055. stmia %r0!, {%r1} @
  1056. stmia %r0!, {%r1} @
  1057. mrs %r1, CPSR @ Save CPSR.
  1058. stmia %r0!, {%r1} @
  1059. mov %r3, %sp @ Put SP in R3 because no pushing SP.
  1060. stmia %r0!, {%r3-%r11} @ Save SP and R4-R11.
  1061. mrs %r1, CPSR @ Get the current mode and status.
  1062. cpsid if, #ARM_MODE_SYSTEM @ Get to user mode (disable interrupts).
  1063. mov %r2, %sp @ Get banked SP.
  1064. stmia %r0!, {%r2, %lr} @ Save banked registers.
  1065. cpsid if, #ARM_MODE_IRQ @ Get to interrupt mode.
  1066. mov %r2, %sp @ Get banked SP.
  1067. stmia %r0!, {%r2, %lr} @ Save banked registers.
  1068. cpsid if, #ARM_MODE_FIQ @ Get to fast interrupt mode.
  1069. mov %r2, %sp @ Get banked SP.
  1070. stmia %r0!, {%r2, %lr} @ Save banked registers.
  1071. cpsid if, #ARM_MODE_ABORT @ Get to abort mode.
  1072. mov %r2, %sp @ Get banked SP.
  1073. stmia %r0!, {%r2, %lr} @ Save banked registers.
  1074. cpsid if, #ARM_MODE_UNDEF @ Get to undefined instruction mode.
  1075. mov %r2, %sp @ Get banked SP.
  1076. stmia %r0!, {%r2, %lr} @ Save banked registers.
  1077. msr CPSR, %r1 @ Restore interrupts and mode.
  1078. stmia %r0!, {%r0} @ Remember the VA right here.
  1079. mrc p15, 0, %r1, c1, c0, 0 @ Save SCTLR.
  1080. stmia %r0!, {%r1} @
  1081. mrc p15, 0, %r1, c2, c0, 0 @ Save TTBR0.
  1082. stmia %r0!, {%r1} @
  1083. mrc p15, 0, %r1, c2, c0, 1 @ Save TTBR1.
  1084. stmia %r0!, {%r1} @
  1085. mrc p15, 0, %r1, c1, c0, 1 @ Save ACTLR.
  1086. stmia %r0!, {%r1} @
  1087. mrc p15, 0, %r1, c1, c0, 2 @ Save CPACR.
  1088. stmia %r0!, {%r1} @
  1089. mrc p15, 0, %r1, c10, c2, 0 @ Save PRRR.
  1090. stmia %r0!, {%r1} @
  1091. mrc p15, 0, %r1, c10, c2, 1 @ Save NMRR.
  1092. stmia %r0!, {%r1} @
  1093. mrc p15, 0, %r1, c13, c0, 1 @ Save CONTEXTIDR.
  1094. stmia %r0!, {%r1} @
  1095. mrc p15, 0, %r1, c5, c0, 0 @ Save DFSR.
  1096. stmia %r0!, {%r1} @
  1097. mrc p15, 0, %r1, c6, c0, 0 @ Save DFAR
  1098. stmia %r0!, {%r1} @
  1099. mrc p15, 0, %r1, c5, c0, 1 @ Save IFSR.
  1100. stmia %r0!, {%r1} @
  1101. mrc p15, 0, %r1, c6, c0, 2 @ Save IFAR.
  1102. stmia %r0!, {%r1} @
  1103. mrc p15, 0, %r1, c3, c0, 0 @ Save DACR
  1104. stmia %r0!, {%r1} @
  1105. mrc p15, 0, %r1, c12, c0, 0 @ Save VBAR.
  1106. stmia %r0!, {%r1} @
  1107. mrc p15, 0, %r1, c13, c0, 4 @ Save TPIDRPRW.
  1108. stmia %r0!, {%r1} @
  1109. mrc p15, 0, %r1, c13, c0, 3 @ Save TPIDRURO.
  1110. stmia %r0!, {%r1} @
  1111. mrc p15, 0, %r1, c13, c0, 2 @ Save TPIDRURW.
  1112. stmia %r0!, {%r1} @
  1113. mrc p15, 0, %r1, c9, c12, 0 @ Save PMCR.
  1114. stmia %r0!, {%r1} @
  1115. mrc p15, 0, %r1, c9, c14, 1 @ Save PMINTENSET.
  1116. stmia %r0!, {%r1} @
  1117. mrc p15, 0, %r1, c9, c14, 0 @ Save PMUSERENR.
  1118. stmia %r0!, {%r1} @
  1119. mrc p15, 0, %r1, c9, c12, 1 @ Save PMCNTENSET.
  1120. stmia %r0!, {%r1} @
  1121. mrc p15, 0, %r1, c9, c13, 0 @ Save PMCCNTR. Start losing time.
  1122. stmia %r0!, {%r1} @
  1123. mov %r0, #0 @ Return 0 initially.
  1124. bx %lr
  1125. END_FUNCTION ArSaveProcessorContext
  1126. ##
  1127. ## VOID
  1128. ## ArRestoreProcessorContext (
  1129. ## PPROCESSOR_CONTEXT Context
  1130. ## )
  1131. ##
  1132. /*++
  1133. Routine Description:
  1134. This routine restores the current processor context, including the
  1135. non-volatile general registers and the system level control registers. This
  1136. function does not return, but instead jumps to the return address from
  1137. the caller of the save context function.
  1138. Arguments:
  1139. Context - Supplies a pointer to the context to restore.
  1140. Return Value:
  1141. Does not return, at least not conventionally.
  1142. --*/
  1143. FUNCTION ArRestoreProcessorContext
  1144. add %r0, %r0, #PROCESSOR_CONTEXT_SIZE @ Jump to the end.
  1145. ldmdb %r0!, {%r1} @
  1146. mcr p15, 0, %r1, c9, c13, 0 @ Restore PMCCNTR. Start losing time.
  1147. ldmdb %r0!, {%r1} @
  1148. mcr p15, 0, %r1, c9, c12, 1 @ Restore PMCNTENSET.
  1149. ldmdb %r0!, {%r1} @
  1150. mcr p15, 0, %r1, c9, c14, 0 @ Restore PMUSERENR.
  1151. ldmdb %r0!, {%r1} @
  1152. mcr p15, 0, %r1, c9, c14, 1 @ Restore PMINTENSET.
  1153. ldmdb %r0!, {%r1} @
  1154. mcr p15, 0, %r1, c9, c12, 0 @ Restore PMCR.
  1155. ldmdb %r0!, {%r1} @
  1156. mcr p15, 0, %r1, c13, c0, 2 @ Restore TPIDRURW.
  1157. ldmdb %r0!, {%r1} @
  1158. mcr p15, 0, %r1, c13, c0, 3 @ Restore TPIDRURO.
  1159. ldmdb %r0!, {%r1} @
  1160. mcr p15, 0, %r1, c13, c0, 4 @ Restore TPIDRPRW.
  1161. ldmdb %r0!, {%r1} @
  1162. mcr p15, 0, %r1, c12, c0, 0 @ Restore VBAR.
  1163. ldmdb %r0!, {%r1} @
  1164. mcr p15, 0, %r1, c3, c0, 0 @ Restore DACR
  1165. ldmdb %r0!, {%r1} @
  1166. mcr p15, 0, %r1, c6, c0, 2 @ Restore IFAR.
  1167. ldmdb %r0!, {%r1} @
  1168. mcr p15, 0, %r1, c5, c0, 1 @ Restore IFSR.
  1169. ldmdb %r0!, {%r1} @
  1170. mcr p15, 0, %r1, c6, c0, 0 @ Restore DFAR
  1171. ldmdb %r0!, {%r1} @
  1172. mcr p15, 0, %r1, c5, c0, 0 @ Restore DFSR.
  1173. ldmdb %r0!, {%r1} @
  1174. mcr p15, 0, %r1, c13, c0, 1 @ Restore CONTEXTIDR.
  1175. ldmdb %r0!, {%r1} @
  1176. mcr p15, 0, %r1, c10, c2, 1 @ Restore NMRR.
  1177. ldmdb %r0!, {%r1} @
  1178. mcr p15, 0, %r1, c10, c2, 0 @ Restore PRRR.
  1179. ldmdb %r0!, {%r1} @
  1180. mcr p15, 0, %r1, c1, c0, 2 @ Restore CPACR.
  1181. ##
  1182. ## Sometimes the ACTLR cannot be written in non-secure mode, so only try to
  1183. ## write it if it appears to need restoring.
  1184. ##
  1185. mrc p15, 0, %r2, c1, c0, 1 @ Get current ACTLR.
  1186. ldmdb %r0!, {%r1} @ Load saved one.
  1187. cmp %r1, %r2 @ Compare.
  1188. beq ArRestoreProcessorContextAfterActlr
  1189. mcr p15, 0, %r1, c1, c0, 1 @ Restore ACTLR.
  1190. ArRestoreProcessorContextAfterActlr:
  1191. ldmdb %r0!, {%r1} @
  1192. mcr p15, 0, %r1, c2, c0, 1 @ Restore TTBR1.
  1193. ldmdb %r0!, {%r1} @
  1194. mcr p15, 0, %r1, c2, c0, 0 @ Restore TTBR0.
  1195. ##
  1196. ## This next bit is tricky, because paging may suddenly become enabled.
  1197. ## This code must be identity mapped, but the context might not be. Load
  1198. ## the SCTLR and the virtual address of the next structure member. Then
  1199. ## restore SCTLR and continue the restore from the virtual address.
  1200. ##
  1201. ldmdb %r0!, {%r1} @ Get SCTLR.
  1202. ldmdb %r0, {%r2} @ Also get the VA of the remainder.
  1203. mov %r0, %r2 @ Make it the new current pointer.
  1204. mcr p15, 0, %r1, c1, c0, 0 @ Restore SCTLR.
  1205. ##
  1206. ## The paging context may have changed (and observed a wonky ASID in the
  1207. ## process), so some invalidations are in order.
  1208. ##
  1209. mcr p15, 0, %r0, c7, c5, 0 @ ICIALLU, Invalidate I-Cache.
  1210. BPIALL @ BPIALL, Invalidate Branch Predictor.
  1211. mcr p15, 0, %r0, c8, c7, 0 @ Clear the TLB, TLBIALL.
  1212. DSB @ Data synchronization barrier.
  1213. ISB @ Instruction syncrhonization barrier.
  1214. ##
  1215. ## Restore the banked registers.
  1216. ##
  1217. cpsid if, #ARM_MODE_UNDEF @ Get to undefined instruction mode.
  1218. ldmdb %r0!, {%r1, %lr} @ Restore banked registers.
  1219. mov %sp, %r1 @ Restore banked SP.
  1220. cpsid if, #ARM_MODE_ABORT @ Get to abort mode.
  1221. ldmdb %r0!, {%r1, %lr} @ Restore banked registers.
  1222. mov %sp, %r1 @ Restore banked SP.
  1223. cpsid if, #ARM_MODE_FIQ @ Get to fast interrupt mode.
  1224. ldmdb %r0!, {%r1, %lr} @ Restore banked registers.
  1225. mov %sp, %r1 @ Restore banked SP.
  1226. cpsid if, #ARM_MODE_IRQ @ Get to interrupt mode.
  1227. ldmdb %r0!, {%r1, %lr} @ Restore banked registers.
  1228. mov %sp, %r1 @ Restore banked SP.
  1229. cpsid if, #ARM_MODE_SYSTEM @ Get to user mode (disable interrupts).
  1230. ldmdb %r0!, {%r1, %lr} @ Restore banked registers.
  1231. mov %sp, %r1 @ Restore banked SP.
  1232. cpsid if, #ARM_MODE_SVC @ Get back to SVC mode.
  1233. ##
  1234. ## Restore the general registers and jump back to the return of the
  1235. ## save context function.
  1236. ##
  1237. mov %r12, %r0 @ Move to a free register.
  1238. ldmdb %r12!, {%r3-%r11} @ Restore general context.
  1239. mov %sp, %r3 @ Restore stack.
  1240. ldmdb %r12!, {%r0-%r3,%lr} @ Restore arguments and CPSR.
  1241. msr CPSR, %lr @ Restore CPSR.
  1242. ldr %r12, [%r12, #-4] @ Read the last value: PC.
  1243. mov %lr, #0 @ Zero out lr for goodwill.
  1244. bx %r12 @ Jump to the return address.
  1245. END_FUNCTION ArRestoreProcessorContext
  1246. ##
  1247. ## ULONG
  1248. ## ArGetMainIdRegister (
  1249. ## VOID
  1250. ## )
  1251. ##
  1252. /*++
  1253. Routine Description:
  1254. This routine gets the Main ID Register (MIDR).
  1255. Arguments:
  1256. None.
  1257. Return Value:
  1258. Returns the contents of the register.
  1259. --*/
  1260. FUNCTION ArGetMainIdRegister
  1261. mrc p15, 0, %r0, c0, c0, 0
  1262. bx %lr
  1263. END_FUNCTION ArGetMainIdRegister
  1264. ##
  1265. ## ULONG
  1266. ## ArGetCoprocessorAccessRegister (
  1267. ## VOID
  1268. ## )
  1269. ##
  1270. /*++
  1271. Routine Description:
  1272. This routine gets the Coprocessor Access Control Register (CPACR).
  1273. Arguments:
  1274. None.
  1275. Return Value:
  1276. Returns the contents of the register.
  1277. --*/
  1278. FUNCTION ArGetCoprocessorAccessRegister
  1279. mrc p15, 0, %r0, c1, c0, 2
  1280. bx %lr
  1281. END_FUNCTION ArGetCoprocessorAccessRegister
  1282. ##
  1283. ## VOID
  1284. ## ArSetCoprocessorAccessRegister (
  1285. ## ULONG Value
  1286. ## )
  1287. ##
  1288. /*++
  1289. Routine Description:
  1290. This routine sets the Coprocessor Access Control Register (CPACR).
  1291. Arguments:
  1292. Value - Supplies the value to write.
  1293. Return Value:
  1294. None.
  1295. --*/
  1296. FUNCTION ArSetCoprocessorAccessRegister
  1297. mcr p15, 0, %r0, c1, c0, 2
  1298. bx %lr
  1299. END_FUNCTION ArSetCoprocessorAccessRegister
  1300. ##
  1301. ## ULONG
  1302. ## ArGetFloatingPointIdRegister (
  1303. ## VOID
  1304. ## )
  1305. ##
  1306. /*++
  1307. Routine Description:
  1308. This routine gets the Floating Point unit ID register (FPSID).
  1309. Arguments:
  1310. None.
  1311. Return Value:
  1312. Returns the contents of the register.
  1313. --*/
  1314. FUNCTION ArGetFloatingPointIdRegister
  1315. vmrs %r0, FPSID
  1316. bx %lr
  1317. END_FUNCTION ArGetFloatingPointIdRegister
  1318. ##
  1319. ## ULONG
  1320. ## ArGetMvfr0Register (
  1321. ## VOID
  1322. ## )
  1323. ##
  1324. /*++
  1325. Routine Description:
  1326. This routine gets the floating point extensions identification register
  1327. (MVFR0).
  1328. Arguments:
  1329. None.
  1330. Return Value:
  1331. Returns the contents of the register.
  1332. --*/
  1333. FUNCTION ArGetMvfr0Register
  1334. vmrs %r0, MVFR0
  1335. bx %lr
  1336. END_FUNCTION ArGetMvfr0Register
  1337. ##
  1338. ## ULONG
  1339. ## ArGetVfpExceptionRegister (
  1340. ## VOID
  1341. ## )
  1342. ##
  1343. /*++
  1344. Routine Description:
  1345. This routine gets the floating point exception control register (FPEXC).
  1346. Arguments:
  1347. None.
  1348. Return Value:
  1349. Returns the contents of the register.
  1350. --*/
  1351. FUNCTION ArGetVfpExceptionRegister
  1352. vmrs %r0, FPEXC
  1353. bx %lr
  1354. END_FUNCTION ArGetVfpExceptionRegister
  1355. ##
  1356. ## VOID
  1357. ## ArSetVfpExceptionRegister (
  1358. ## ULONG Value
  1359. ## )
  1360. ##
  1361. /*++
  1362. Routine Description:
  1363. This routine sets the floating point exception control register (FPEXC).
  1364. Arguments:
  1365. Value - Supplies the new value to set.
  1366. Return Value:
  1367. None.
  1368. --*/
  1369. FUNCTION ArSetVfpExceptionRegister
  1370. vmsr FPEXC, %r0
  1371. bx %lr
  1372. END_FUNCTION ArSetVfpExceptionRegister
  1373. ##
  1374. ## ULONG
  1375. ## ArGetVfpInstructionRegister (
  1376. ## VOID
  1377. ## )
  1378. ##
  1379. /*++
  1380. Routine Description:
  1381. This routine gets the floating point instruction register (FPINST).
  1382. Arguments:
  1383. None.
  1384. Return Value:
  1385. Returns the contents of the register.
  1386. --*/
  1387. FUNCTION ArGetVfpInstructionRegister
  1388. mrc p10, 7, %r0, c9, c0, 0
  1389. bx %lr
  1390. END_FUNCTION ArGetVfpInstructionRegister
  1391. ##
  1392. ## ULONG
  1393. ## ArGetFpscr (
  1394. ## VOID
  1395. ## )
  1396. ##
  1397. /*++
  1398. Routine Description:
  1399. This routine gets the floating point status and control register (FPSCR).
  1400. Arguments:
  1401. None.
  1402. Return Value:
  1403. Returns the contents of the register.
  1404. --*/
  1405. FUNCTION ArGetFpscr
  1406. vmrs %r0, FPSCR @ Get FPSCR.
  1407. bx %lr
  1408. END_FUNCTION ArGetFpscr
  1409. ##
  1410. ## VOID
  1411. ## ArSaveVfp (
  1412. ## PFPU_CONTEXT Context,
  1413. ## BOOL SimdSupport
  1414. ## )
  1415. ##
  1416. /*++
  1417. Routine Description:
  1418. This routine saves the Vector Floating Point unit state.
  1419. Arguments:
  1420. Context - Supplies a pointer where the context will be saved.
  1421. SimdSupport - Supplies a boolean indicating whether the VFP unit contains
  1422. 32 64-bit registers (TRUE) or 16 64-bit registers (FALSE).
  1423. Return Value:
  1424. None.
  1425. --*/
  1426. FUNCTION ArSaveVfp
  1427. stc p11, c0, [%r0], #16*8 @ Save D0-D15 (stmia).
  1428. cmp %r1, #0 @ Test for no SIMD support.
  1429. ITE(ne) @ If equal then else.
  1430. stclne p11, c0, [%r0], #16*8 @ Save D16-D31 if SIMD support.
  1431. addeq %r0, %r0, #16*8 @ Skip those registers if not.
  1432. vmrs %r2, FPSCR @ Get FPSCR.
  1433. str %r2, [%r0] @ Store it.
  1434. bx %lr @ Return.
  1435. END_FUNCTION ArSaveVfp
  1436. ##
  1437. ## VOID
  1438. ## ArRestoreVfp (
  1439. ## PFPU_CONTEXT Context,
  1440. ## BOOL SimdSupport
  1441. ## )
  1442. ##
  1443. /*++
  1444. Routine Description:
  1445. This routine restores the Vector Floating Point unit state into the
  1446. hardware.
  1447. Arguments:
  1448. Context - Supplies a pointer to the context to restore.
  1449. SimdSupport - Supplies a boolean indicating whether the VFP unit contains
  1450. 32 64-bit registers (TRUE) or 16 64-bit registers (FALSE).
  1451. Return Value:
  1452. None.
  1453. --*/
  1454. FUNCTION ArRestoreVfp
  1455. ldc p11, c0, [%r0], #16*8 @ Restore D0-D15 (ldmia).
  1456. cmp %r1, #0 @ Test for no SIMD support.
  1457. ITE(ne) @ If equal then else.
  1458. ldclne p11, c0, [%r0], #16*8 @ Restore D16-D31 if SIMD support.
  1459. addeq %r0, %r0, #16*8 @ Skip those registers if not.
  1460. ldr %r2, [%r0] @ Get FPSCR.
  1461. vmsr FPSCR, %r2 @ Restore FPSCR.
  1462. bx %lr @ Return.
  1463. END_FUNCTION ArRestoreVfp
  1464. ##
  1465. ## --------------------------------------------------------- Internal Functions
  1466. ##