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