AsmMacroIoLib.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /** @file
  2. Macros to work around lack of Apple support for LDR register, =expr
  3. Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
  4. Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
  5. This program and the accompanying materials
  6. are licensed and made available under the terms and conditions of the BSD License
  7. which accompanies this distribution. The full text of the license may be found at
  8. http://opensource.org/licenses/bsd-license.php
  9. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  11. **/
  12. #ifndef __MACRO_IO_LIB_H__
  13. #define __MACRO_IO_LIB_H__
  14. #if defined(__APPLE__)
  15. //
  16. // ldr reg, =expr does not work with current Apple tool chain. So do the work our selves
  17. //
  18. // returns _Data in R0 and _Address in R1
  19. #define MmioWrite32(_Address, _Data) \
  20. ldr r1, [pc, #8] ; \
  21. ldr r0, [pc, #8] ; \
  22. str r0, [r1] ; \
  23. b 1f ; \
  24. .long (_Address) ; \
  25. .long (_Data) ; \
  26. 1:
  27. // returns _Data in R0 and _Address in R1, and _OrData in r2
  28. #define MmioOr32(_Address, _OrData) \
  29. ldr r1, [pc, #16] ; \
  30. ldr r2, [pc, #16] ; \
  31. ldr r0, [r1] ; \
  32. orr r0, r0, r2 ; \
  33. str r0, [r1] ; \
  34. b 1f ; \
  35. .long (_Address) ; \
  36. .long (_OrData) ; \
  37. 1:
  38. // returns _Data in R0 and _Address in R1, and _OrData in r2
  39. #define MmioAnd32(_Address, _AndData) \
  40. ldr r1, [pc, #16] ; \
  41. ldr r2, [pc, #16] ; \
  42. ldr r0, [r1] ; \
  43. and r0, r0, r2 ; \
  44. str r0, [r1] ; \
  45. b 1f ; \
  46. .long (_Address) ; \
  47. .long (_AndData) ; \
  48. 1:
  49. // returns result in R0, _Address in R1, and _OrData in r2
  50. #define MmioAndThenOr32(_Address, _AndData, _OrData) \
  51. ldr r1, [pc, #24] ; \
  52. ldr r0, [r1] ; \
  53. ldr r2, [pc, #20] ; \
  54. and r0, r0, r2 ; \
  55. ldr r2, [pc, #16] ; \
  56. orr r0, r0, r2 ; \
  57. str r0, [r1] ; \
  58. b 1f ; \
  59. .long (_Address) ; \
  60. .long (_AndData) ; \
  61. .long (_OrData) ; \
  62. 1:
  63. // returns _Data in _Reg and _Address in R1
  64. #define MmioWriteFromReg32(_Address, _Reg) \
  65. ldr r1, [pc, #4] ; \
  66. str _Reg, [r1] ; \
  67. b 1f ; \
  68. .long (_Address) ; \
  69. 1:
  70. // returns _Data in R0 and _Address in R1
  71. #define MmioRead32(_Address) \
  72. ldr r1, [pc, #4] ; \
  73. ldr r0, [r1] ; \
  74. b 1f ; \
  75. .long (_Address) ; \
  76. 1:
  77. // returns _Data in Reg and _Address in R1
  78. #define MmioReadToReg32(_Address, _Reg) \
  79. ldr r1, [pc, #4] ; \
  80. ldr _Reg, [r1] ; \
  81. b 1f ; \
  82. .long (_Address) ; \
  83. 1:
  84. // load R0 with _Data
  85. #define LoadConstant(_Data) \
  86. ldr r0, [pc, #0] ; \
  87. b 1f ; \
  88. .long (_Data) ; \
  89. 1:
  90. // load _Reg with _Data
  91. #define LoadConstantToReg(_Data, _Reg) \
  92. ldr _Reg, [pc, #0] ; \
  93. b 1f ; \
  94. .long (_Data) ; \
  95. 1:
  96. // load _Reg with _Data if eq
  97. #define LoadConstantToRegIfEq(_Data, _Reg) \
  98. ldreq _Reg, [pc, #0] ; \
  99. b 1f ; \
  100. .long (_Data) ; \
  101. 1:
  102. // Reserve a region at the top of the Primary Core stack
  103. // for Global variables for the XIP phase
  104. #define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
  105. and Tmp, GlobalSize, #7 ; \
  106. rsbne Tmp, Tmp, #8 ; \
  107. add GlobalSize, GlobalSize, Tmp ; \
  108. sub sp, StackTop, GlobalSize ; \
  109. ; \
  110. mov Tmp, sp ; \
  111. mov GlobalSize, #0x0 ; \
  112. _SetPrimaryStackInitGlobals: ; \
  113. cmp Tmp, StackTop ; \
  114. beq _SetPrimaryStackEnd ; \
  115. str GlobalSize, [Tmp], #4 ; \
  116. b _SetPrimaryStackInitGlobals ; \
  117. _SetPrimaryStackEnd:
  118. // Initialize the Global Variable with '0'
  119. #define InitializePrimaryStack(GlobalSize, Tmp1) \
  120. and Tmp1, GlobalSize, #7 ; \
  121. rsbne Tmp1, Tmp1, #8 ; \
  122. add GlobalSize, GlobalSize, Tmp1 ; \
  123. ; \
  124. mov Tmp1, sp ; \
  125. sub sp, GlobalSize ; \
  126. mov GlobalSize, #0x0 ; \
  127. _InitializePrimaryStackLoop: ; \
  128. cmp Tmp1, sp ; \
  129. bls _InitializePrimaryStackEnd ; \
  130. str GlobalSize, [Tmp1], #-4 ; \
  131. b _InitializePrimaryStackLoop ; \
  132. _InitializePrimaryStackEnd:
  133. #elif defined (__GNUC__)
  134. #define MmioWrite32(Address, Data) \
  135. ldr r1, =Address ; \
  136. ldr r0, =Data ; \
  137. str r0, [r1]
  138. #define MmioOr32(Address, OrData) \
  139. ldr r1, =Address ; \
  140. ldr r2, =OrData ; \
  141. ldr r0, [r1] ; \
  142. orr r0, r0, r2 ; \
  143. str r0, [r1]
  144. #define MmioAnd32(Address, AndData) \
  145. ldr r1, =Address ; \
  146. ldr r2, =AndData ; \
  147. ldr r0, [r1] ; \
  148. and r0, r0, r2 ; \
  149. str r0, [r1]
  150. #define MmioAndThenOr32(Address, AndData, OrData) \
  151. ldr r1, =Address ; \
  152. ldr r0, [r1] ; \
  153. ldr r2, =AndData ; \
  154. and r0, r0, r2 ; \
  155. ldr r2, =OrData ; \
  156. orr r0, r0, r2 ; \
  157. str r0, [r1]
  158. #define MmioWriteFromReg32(Address, Reg) \
  159. ldr r1, =Address ; \
  160. str Reg, [r1]
  161. #define MmioRead32(Address) \
  162. ldr r1, =Address ; \
  163. ldr r0, [r1]
  164. #define MmioReadToReg32(Address, Reg) \
  165. ldr r1, =Address ; \
  166. ldr Reg, [r1]
  167. #define LoadConstant(Data) \
  168. ldr r0, =Data
  169. #define LoadConstantToReg(Data, Reg) \
  170. ldr Reg, =Data
  171. #define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
  172. and Tmp, GlobalSize, #7 ; \
  173. rsbne Tmp, Tmp, #8 ; \
  174. add GlobalSize, GlobalSize, Tmp ; \
  175. sub sp, StackTop, GlobalSize ; \
  176. ; \
  177. mov Tmp, sp ; \
  178. mov GlobalSize, #0x0 ; \
  179. _SetPrimaryStackInitGlobals: ; \
  180. cmp Tmp, StackTop ; \
  181. beq _SetPrimaryStackEnd ; \
  182. str GlobalSize, [Tmp], #4 ; \
  183. b _SetPrimaryStackInitGlobals ; \
  184. _SetPrimaryStackEnd:
  185. // Initialize the Global Variable with '0'
  186. #define InitializePrimaryStack(GlobalSize, Tmp1) \
  187. and Tmp1, GlobalSize, #7 ; \
  188. rsbne Tmp1, Tmp1, #8 ; \
  189. add GlobalSize, GlobalSize, Tmp1 ; \
  190. ; \
  191. mov Tmp1, sp ; \
  192. sub sp, GlobalSize ; \
  193. mov GlobalSize, #0x0 ; \
  194. _InitializePrimaryStackLoop: ; \
  195. cmp Tmp1, sp ; \
  196. bls _InitializePrimaryStackEnd ; \
  197. str GlobalSize, [Tmp1], #-4 ; \
  198. b _InitializePrimaryStackLoop ; \
  199. _InitializePrimaryStackEnd:
  200. #else
  201. //
  202. // Use ARM assembly macros, form armasam
  203. //
  204. // Less magic in the macros if ldr reg, =expr works
  205. //
  206. // returns _Data in R0 and _Address in R1
  207. #define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data
  208. // returns Data in R0 and Address in R1, and OrData in r2
  209. #define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData
  210. // returns _Data in R0 and _Address in R1, and _OrData in r2
  211. #define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData
  212. // returns result in R0, _Address in R1, and _OrData in r2
  213. #define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData
  214. // returns _Data in _Reg and _Address in R1
  215. #define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg
  216. // returns _Data in R0 and _Address in R1
  217. #define MmioRead32(Address) MmioRead32Macro Address
  218. // returns _Data in Reg and _Address in R1
  219. #define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg
  220. // load R0 with _Data
  221. #define LoadConstant(Data) LoadConstantMacro Data
  222. // load _Reg with _Data
  223. #define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg
  224. // conditional load testing eq flag
  225. #define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
  226. #define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
  227. // Initialize the Global Variable with '0'
  228. #define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1
  229. #endif
  230. #endif