1
0

commsup.S 44 KB

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