blob: 6904bdc9b001b030d892607a243737d10fd35237 [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @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) ; \
351:
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) ; \
471:
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) ; \
591:
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) ; \
741:
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) ; \
821:
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) ; \
911:
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) ; \
991:
100
101
102// load R0 with _Data
103#define LoadConstant(_Data) \
104 ldr r0, [pc, #0] ; \
105 b 1f ; \
106 .long (_Data) ; \
1071:
108
109// load _Reg with _Data
110#define LoadConstantToReg(_Data, _Reg) \
111 ldr _Reg, [pc, #0] ; \
112 b 1f ; \
113 .long (_Data) ; \
1141:
115
116// load _Reg with _Data if eq
117#define LoadConstantToRegIfEq(_Data, _Reg) \
118 ldreq _Reg, [pc, #0] ; \
119 b 1f ; \
120 .long (_Data) ; \
1211:
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#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
205 and Tmp, GlobalSize, #7 ; \
206 rsbne Tmp, Tmp, #8 ; \
207 add GlobalSize, GlobalSize, Tmp ; \
208 sub sp, StackTop, GlobalSize ; \
209 ; \
210 mov Tmp, sp ; \
211 mov GlobalSize, #0x0 ; \
212_SetPrimaryStackInitGlobals: ; \
213 cmp Tmp, StackTop ; \
214 beq _SetPrimaryStackEnd ; \
215 str GlobalSize, [Tmp], #4 ; \
216 b _SetPrimaryStackInitGlobals ; \
217_SetPrimaryStackEnd:
218
219// Initialize the Global Variable with '0'
220#define InitializePrimaryStack(GlobalSize, Tmp1) \
221 and Tmp1, GlobalSize, #7 ; \
222 rsbne Tmp1, Tmp1, #8 ; \
223 add GlobalSize, GlobalSize, Tmp1 ; \
224 ; \
225 mov Tmp1, sp ; \
226 sub sp, GlobalSize ; \
227 mov GlobalSize, #0x0 ; \
228_InitializePrimaryStackLoop: ; \
229 cmp Tmp1, sp ; \
230 bls _InitializePrimaryStackEnd ; \
231 str GlobalSize, [Tmp1, #-4]! ; \
232 b _InitializePrimaryStackLoop ; \
233_InitializePrimaryStackEnd:
234
235#else
236
237//
238// Use ARM assembly macros, form armasam
239//
240// Less magic in the macros if ldr reg, =expr works
241//
242
243// returns _Data in R0 and _Address in R1
244
245
246
247#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data
248
249
250
251
252// returns Data in R0 and Address in R1, and OrData in r2
253#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData
254
255
256// returns _Data in R0 and _Address in R1, and _OrData in r2
257
258
259#define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData
260
261// returns result in R0, _Address in R1, and _OrData in r2
262
263
264#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData
265
266
267// returns _Data in _Reg and _Address in R1
268
269
270#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg
271
272// returns _Data in R0 and _Address in R1
273
274
275#define MmioRead32(Address) MmioRead32Macro Address
276
277// returns _Data in Reg and _Address in R1
278
279
280#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg
281
282
283// load R0 with _Data
284
285
286#define LoadConstant(Data) LoadConstantMacro Data
287
288// load _Reg with _Data
289
290
291#define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg
292
293// conditional load testing eq flag
294#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
295
296#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
297
298// Initialize the Global Variable with '0'
299#define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1
300
301#endif
302
303#endif