]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Include/AsmMacroIoLib.h
ArmPlatformPkg/ArmPlatformStackLib: Introduced helper library to initialize stacks
[mirror_edk2.git] / ArmPkg / Include / AsmMacroIoLib.h
CommitLineData
2ef2b01e
A
1/** @file\r
2 Macros to work around lack of Apple support for LDR register, =expr\r
3\r
d6ebcab7 4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
1377db63 5 Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>\r
2ef2b01e 6\r
d6ebcab7 7 This program and the accompanying materials\r
2ef2b01e
A
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17\r
18#ifndef __MACRO_IO_LIB_H__\r
19#define __MACRO_IO_LIB_H__\r
20\r
21#if defined(__APPLE__)\r
22\r
23//\r
24// ldr reg, =expr does not work with current Apple tool chain. So do the work our selves\r
25//\r
26\r
27// returns _Data in R0 and _Address in R1\r
28#define MmioWrite32(_Address, _Data) \\r
29 ldr r1, [pc, #8] ; \\r
30 ldr r0, [pc, #8] ; \\r
31 str r0, [r1] ; \\r
32 b 1f ; \\r
33 .long (_Address) ; \\r
34 .long (_Data) ; \\r
351:\r
36\r
37// returns _Data in R0 and _Address in R1, and _OrData in r2\r
38#define MmioOr32(_Address, _OrData) \\r
39 ldr r1, [pc, #16] ; \\r
40 ldr r2, [pc, #16] ; \\r
41 ldr r0, [r1] ; \\r
42 orr r0, r0, r2 ; \\r
43 str r0, [r1] ; \\r
44 b 1f ; \\r
45 .long (_Address) ; \\r
46 .long (_OrData) ; \\r
471:\r
48\r
49// returns _Data in R0 and _Address in R1, and _OrData in r2\r
50#define MmioAnd32(_Address, _AndData) \\r
51 ldr r1, [pc, #16] ; \\r
52 ldr r2, [pc, #16] ; \\r
53 ldr r0, [r1] ; \\r
54 and r0, r0, r2 ; \\r
55 str r0, [r1] ; \\r
56 b 1f ; \\r
57 .long (_Address) ; \\r
58 .long (_AndData) ; \\r
591:\r
60\r
61// returns result in R0, _Address in R1, and _OrData in r2\r
62#define MmioAndThenOr32(_Address, _AndData, _OrData) \\r
63 ldr r1, [pc, #24] ; \\r
64 ldr r0, [r1] ; \\r
65 ldr r2, [pc, #20] ; \\r
66 and r0, r0, r2 ; \\r
67 ldr r2, [pc, #16] ; \\r
68 orr r0, r0, r2 ; \\r
69 str r0, [r1] ; \\r
70 b 1f ; \\r
71 .long (_Address) ; \\r
72 .long (_AndData) ; \\r
73 .long (_OrData) ; \\r
741:\r
75\r
76// returns _Data in _Reg and _Address in R1\r
77#define MmioWriteFromReg32(_Address, _Reg) \\r
78 ldr r1, [pc, #4] ; \\r
79 str _Reg, [r1] ; \\r
80 b 1f ; \\r
81 .long (_Address) ; \\r
821:\r
83\r
84\r
85// returns _Data in R0 and _Address in R1\r
86#define MmioRead32(_Address) \\r
87 ldr r1, [pc, #4] ; \\r
88 ldr r0, [r1] ; \\r
89 b 1f ; \\r
90 .long (_Address) ; \\r
911:\r
92\r
93// returns _Data in Reg and _Address in R1\r
94#define MmioReadToReg32(_Address, _Reg) \\r
95 ldr r1, [pc, #4] ; \\r
96 ldr _Reg, [r1] ; \\r
97 b 1f ; \\r
98 .long (_Address) ; \\r
991:\r
100\r
101\r
102// load R0 with _Data\r
103#define LoadConstant(_Data) \\r
104 ldr r0, [pc, #0] ; \\r
105 b 1f ; \\r
106 .long (_Data) ; \\r
1071:\r
108\r
109// load _Reg with _Data\r
110#define LoadConstantToReg(_Data, _Reg) \\r
111 ldr _Reg, [pc, #0] ; \\r
112 b 1f ; \\r
113 .long (_Data) ; \\r
1141:\r
115\r
116// load _Reg with _Data if eq\r
117#define LoadConstantToRegIfEq(_Data, _Reg) \\r
118 ldreq _Reg, [pc, #0] ; \\r
119 b 1f ; \\r
120 .long (_Data) ; \\r
1211:\r
122\r
89bbce11 123// Convert the (ClusterId,CoreId) into a Core Position\r
124// We assume there are 4 cores per cluster\r
a32dae48 125#define GetCorePositionFromMpId(Pos, MpId, Tmp) \\r
89bbce11 126 lsr Pos, MpId, #6 ; \\r
127 and Tmp, MpId, #3 ; \\r
128 add Pos, Pos, Tmp\r
129\r
130// Reserve a region at the top of the Primary Core stack\r
131// for Global variables for the XIP phase\r
132#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \\r
133 and Tmp, GlobalSize, #7 ; \\r
134 rsbne Tmp, Tmp, #8 ; \\r
135 add GlobalSize, GlobalSize, Tmp ; \\r
1377db63 136 sub sp, StackTop, GlobalSize ; \\r
137 ; \\r
138 mov Tmp, sp ; \\r
139 mov GlobalSize, #0x0 ; \\r
140_SetPrimaryStackInitGlobals: ; \\r
141 cmp Tmp, StackTop ; \\r
142 beq _SetPrimaryStackEnd ; \\r
143 str GlobalSize, [Tmp], #4 ; \\r
144 b _SetPrimaryStackInitGlobals ; \\r
145_SetPrimaryStackEnd:\r
89bbce11 146\r
17839a45 147// Initialize the Global Variable with '0'\r
148#define InitializePrimaryStack(GlobalSize, Tmp1) \\r
149 and Tmp1, GlobalSize, #7 ; \\r
150 rsbne Tmp1, Tmp1, #8 ; \\r
151 add GlobalSize, GlobalSize, Tmp1 ; \\r
152 ; \\r
153 mov Tmp1, sp ; \\r
154 sub sp, GlobalSize ; \\r
155 mov GlobalSize, #0x0 ; \\r
156_InitializePrimaryStackLoop: ; \\r
157 cmp Tmp1, sp ; \\r
158 bls _InitializePrimaryStackEnd ; \\r
159 str GlobalSize, [Tmp1], #-4 ; \\r
160 b _InitializePrimaryStackLoop ; \\r
161_InitializePrimaryStackEnd:\r
2ef2b01e
A
162\r
163#elif defined (__GNUC__)\r
164\r
165#define MmioWrite32(Address, Data) \\r
166 ldr r1, =Address ; \\r
167 ldr r0, =Data ; \\r
168 str r0, [r1]\r
169 \r
170#define MmioOr32(Address, OrData) \\r
171 ldr r1, =Address ; \\r
172 ldr r2, =OrData ; \\r
173 ldr r0, [r1] ; \\r
174 orr r0, r0, r2 ; \\r
175 str r0, [r1]\r
176\r
177#define MmioAnd32(Address, AndData) \\r
178 ldr r1, =Address ; \\r
179 ldr r2, =AndData ; \\r
180 ldr r0, [r1] ; \\r
181 and r0, r0, r2 ; \\r
182 str r0, [r1]\r
183\r
184#define MmioAndThenOr32(Address, AndData, OrData) \\r
185 ldr r1, =Address ; \\r
186 ldr r0, [r1] ; \\r
187 ldr r2, =AndData ; \\r
188 and r0, r0, r2 ; \\r
189 ldr r2, =OrData ; \\r
190 orr r0, r0, r2 ; \\r
191 str r0, [r1] \r
192\r
193#define MmioWriteFromReg32(Address, Reg) \\r
194 ldr r1, =Address ; \\r
195 str Reg, [r1]\r
196\r
197#define MmioRead32(Address) \\r
198 ldr r1, =Address ; \\r
199 ldr r0, [r1]\r
200\r
201#define MmioReadToReg32(Address, Reg) \\r
202 ldr r1, =Address ; \\r
203 ldr Reg, [r1]\r
204\r
205#define LoadConstant(Data) \\r
206 ldr r0, =Data\r
207\r
208#define LoadConstantToReg(Data, Reg) \\r
209 ldr Reg, =Data\r
210 \r
a32dae48 211#define GetCorePositionFromMpId(Pos, MpId, Tmp) \\r
2dbcb8f0 212 lsr Pos, MpId, #6 ; \\r
213 and Tmp, MpId, #3 ; \\r
214 add Pos, Pos, Tmp\r
215\r
216#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \\r
217 and Tmp, GlobalSize, #7 ; \\r
218 rsbne Tmp, Tmp, #8 ; \\r
219 add GlobalSize, GlobalSize, Tmp ; \\r
1377db63 220 sub sp, StackTop, GlobalSize ; \\r
221 ; \\r
222 mov Tmp, sp ; \\r
223 mov GlobalSize, #0x0 ; \\r
224_SetPrimaryStackInitGlobals: ; \\r
225 cmp Tmp, StackTop ; \\r
226 beq _SetPrimaryStackEnd ; \\r
227 str GlobalSize, [Tmp], #4 ; \\r
228 b _SetPrimaryStackInitGlobals ; \\r
229_SetPrimaryStackEnd:\r
2dbcb8f0 230\r
17839a45 231// Initialize the Global Variable with '0'\r
232#define InitializePrimaryStack(GlobalSize, Tmp1) \\r
233 and Tmp1, GlobalSize, #7 ; \\r
234 rsbne Tmp1, Tmp1, #8 ; \\r
235 add GlobalSize, GlobalSize, Tmp1 ; \\r
236 ; \\r
237 mov Tmp1, sp ; \\r
238 sub sp, GlobalSize ; \\r
239 mov GlobalSize, #0x0 ; \\r
240_InitializePrimaryStackLoop: ; \\r
241 cmp Tmp1, sp ; \\r
242 bls _InitializePrimaryStackEnd ; \\r
243 str GlobalSize, [Tmp1], #-4 ; \\r
244 b _InitializePrimaryStackLoop ; \\r
245_InitializePrimaryStackEnd:\r
246\r
2ef2b01e
A
247#else\r
248\r
249//\r
250// Use ARM assembly macros, form armasam \r
251//\r
252// Less magic in the macros if ldr reg, =expr works\r
253//\r
254\r
255// returns _Data in R0 and _Address in R1\r
256\r
257\r
258\r
259#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data\r
260\r
261\r
262\r
263\r
264// returns Data in R0 and Address in R1, and OrData in r2\r
265#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData\r
266 \r
267\r
268// returns _Data in R0 and _Address in R1, and _OrData in r2\r
269\r
270\r
271#define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData\r
272\r
273// returns result in R0, _Address in R1, and _OrData in r2\r
274\r
275\r
276#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData\r
277\r
278\r
279// returns _Data in _Reg and _Address in R1\r
280\r
281\r
282#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg\r
283\r
284// returns _Data in R0 and _Address in R1\r
285\r
286\r
287#define MmioRead32(Address) MmioRead32Macro Address\r
288\r
289// returns _Data in Reg and _Address in R1\r
290\r
291\r
292#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg\r
293\r
294\r
295// load R0 with _Data\r
296\r
297\r
298#define LoadConstant(Data) LoadConstantMacro Data\r
299\r
300// load _Reg with _Data\r
301\r
302\r
303#define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg\r
304\r
305// conditional load testing eq flag\r
306#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg\r
307\r
a32dae48 308#define GetCorePositionFromMpId(Pos, MpId, Tmp) GetCorePositionFromMpId Pos, MpId, Tmp\r
2ef2b01e 309\r
2dbcb8f0 310#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp\r
2ef2b01e 311\r
17839a45 312// Initialize the Global Variable with '0'\r
313#define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1\r
314\r
2dbcb8f0 315#endif\r
2ef2b01e
A
316\r
317#endif\r