]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Include/AsmMacroIoLib.h
ArmPlatformPkg/ArmPlatformLib: Added support for ArmPlatformIsPrimaryCore()
[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
bebda7ce 125// Note: 0xFFFF is the magic value for ARM_CORE_MASK | ARM_CLUSTER_MASK\r
126#define GetCorePositionFromMpId(Pos, MpId, Tmp) \\r
127 ldr Tmp, =0xFFFF \\r
128 and MpId, Tmp \\r
129 lsr Pos, MpId, #6 ; \\r
130 and Tmp, MpId, #3 ; \\r
89bbce11 131 add Pos, Pos, Tmp\r
132\r
133// Reserve a region at the top of the Primary Core stack\r
134// for Global variables for the XIP phase\r
135#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \\r
136 and Tmp, GlobalSize, #7 ; \\r
137 rsbne Tmp, Tmp, #8 ; \\r
138 add GlobalSize, GlobalSize, Tmp ; \\r
1377db63 139 sub sp, StackTop, GlobalSize ; \\r
140 ; \\r
141 mov Tmp, sp ; \\r
142 mov GlobalSize, #0x0 ; \\r
143_SetPrimaryStackInitGlobals: ; \\r
144 cmp Tmp, StackTop ; \\r
145 beq _SetPrimaryStackEnd ; \\r
146 str GlobalSize, [Tmp], #4 ; \\r
147 b _SetPrimaryStackInitGlobals ; \\r
148_SetPrimaryStackEnd:\r
89bbce11 149\r
17839a45 150// Initialize the Global Variable with '0'\r
151#define InitializePrimaryStack(GlobalSize, Tmp1) \\r
152 and Tmp1, GlobalSize, #7 ; \\r
153 rsbne Tmp1, Tmp1, #8 ; \\r
154 add GlobalSize, GlobalSize, Tmp1 ; \\r
155 ; \\r
156 mov Tmp1, sp ; \\r
157 sub sp, GlobalSize ; \\r
158 mov GlobalSize, #0x0 ; \\r
159_InitializePrimaryStackLoop: ; \\r
160 cmp Tmp1, sp ; \\r
161 bls _InitializePrimaryStackEnd ; \\r
162 str GlobalSize, [Tmp1], #-4 ; \\r
163 b _InitializePrimaryStackLoop ; \\r
164_InitializePrimaryStackEnd:\r
2ef2b01e
A
165\r
166#elif defined (__GNUC__)\r
167\r
168#define MmioWrite32(Address, Data) \\r
169 ldr r1, =Address ; \\r
170 ldr r0, =Data ; \\r
171 str r0, [r1]\r
172 \r
173#define MmioOr32(Address, OrData) \\r
174 ldr r1, =Address ; \\r
175 ldr r2, =OrData ; \\r
176 ldr r0, [r1] ; \\r
177 orr r0, r0, r2 ; \\r
178 str r0, [r1]\r
179\r
180#define MmioAnd32(Address, AndData) \\r
181 ldr r1, =Address ; \\r
182 ldr r2, =AndData ; \\r
183 ldr r0, [r1] ; \\r
184 and r0, r0, r2 ; \\r
185 str r0, [r1]\r
186\r
187#define MmioAndThenOr32(Address, AndData, OrData) \\r
188 ldr r1, =Address ; \\r
189 ldr r0, [r1] ; \\r
190 ldr r2, =AndData ; \\r
191 and r0, r0, r2 ; \\r
192 ldr r2, =OrData ; \\r
193 orr r0, r0, r2 ; \\r
194 str r0, [r1] \r
195\r
196#define MmioWriteFromReg32(Address, Reg) \\r
197 ldr r1, =Address ; \\r
198 str Reg, [r1]\r
199\r
200#define MmioRead32(Address) \\r
201 ldr r1, =Address ; \\r
202 ldr r0, [r1]\r
203\r
204#define MmioReadToReg32(Address, Reg) \\r
205 ldr r1, =Address ; \\r
206 ldr Reg, [r1]\r
207\r
208#define LoadConstant(Data) \\r
209 ldr r0, =Data\r
210\r
211#define LoadConstantToReg(Data, Reg) \\r
212 ldr Reg, =Data\r
bebda7ce 213\r
214// Convert the (ClusterId,CoreId) into a Core Position\r
215// We assume there are 4 cores per cluster\r
216// Note: 0xFFFF is the magic value for ARM_CORE_MASK | ARM_CLUSTER_MASK\r
217#define GetCorePositionFromMpId(Pos, MpId, Tmp) \\r
218 ldr Tmp, =0xFFFF ; \\r
219 and MpId, Tmp ; \\r
220 lsr Pos, MpId, #6 ; \\r
221 and Tmp, MpId, #3 ; \\r
2dbcb8f0 222 add Pos, Pos, Tmp\r
223\r
224#define SetPrimaryStack(StackTop, GlobalSize, Tmp) \\r
225 and Tmp, GlobalSize, #7 ; \\r
226 rsbne Tmp, Tmp, #8 ; \\r
227 add GlobalSize, GlobalSize, Tmp ; \\r
1377db63 228 sub sp, StackTop, GlobalSize ; \\r
229 ; \\r
230 mov Tmp, sp ; \\r
231 mov GlobalSize, #0x0 ; \\r
232_SetPrimaryStackInitGlobals: ; \\r
233 cmp Tmp, StackTop ; \\r
234 beq _SetPrimaryStackEnd ; \\r
235 str GlobalSize, [Tmp], #4 ; \\r
236 b _SetPrimaryStackInitGlobals ; \\r
237_SetPrimaryStackEnd:\r
2dbcb8f0 238\r
17839a45 239// Initialize the Global Variable with '0'\r
240#define InitializePrimaryStack(GlobalSize, Tmp1) \\r
241 and Tmp1, GlobalSize, #7 ; \\r
242 rsbne Tmp1, Tmp1, #8 ; \\r
243 add GlobalSize, GlobalSize, Tmp1 ; \\r
244 ; \\r
245 mov Tmp1, sp ; \\r
246 sub sp, GlobalSize ; \\r
247 mov GlobalSize, #0x0 ; \\r
248_InitializePrimaryStackLoop: ; \\r
249 cmp Tmp1, sp ; \\r
250 bls _InitializePrimaryStackEnd ; \\r
251 str GlobalSize, [Tmp1], #-4 ; \\r
252 b _InitializePrimaryStackLoop ; \\r
253_InitializePrimaryStackEnd:\r
254\r
2ef2b01e
A
255#else\r
256\r
257//\r
258// Use ARM assembly macros, form armasam \r
259//\r
260// Less magic in the macros if ldr reg, =expr works\r
261//\r
262\r
263// returns _Data in R0 and _Address in R1\r
264\r
265\r
266\r
267#define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data\r
268\r
269\r
270\r
271\r
272// returns Data in R0 and Address in R1, and OrData in r2\r
273#define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData\r
274 \r
275\r
276// returns _Data in R0 and _Address in R1, and _OrData in r2\r
277\r
278\r
279#define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData\r
280\r
281// returns result in R0, _Address in R1, and _OrData in r2\r
282\r
283\r
284#define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData\r
285\r
286\r
287// returns _Data in _Reg and _Address in R1\r
288\r
289\r
290#define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg\r
291\r
292// returns _Data in R0 and _Address in R1\r
293\r
294\r
295#define MmioRead32(Address) MmioRead32Macro Address\r
296\r
297// returns _Data in Reg and _Address in R1\r
298\r
299\r
300#define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg\r
301\r
302\r
303// load R0 with _Data\r
304\r
305\r
306#define LoadConstant(Data) LoadConstantMacro Data\r
307\r
308// load _Reg with _Data\r
309\r
310\r
311#define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg\r
312\r
313// conditional load testing eq flag\r
314#define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg\r
315\r
a32dae48 316#define GetCorePositionFromMpId(Pos, MpId, Tmp) GetCorePositionFromMpId Pos, MpId, Tmp\r
2ef2b01e 317\r
2dbcb8f0 318#define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp\r
2ef2b01e 319\r
17839a45 320// Initialize the Global Variable with '0'\r
321#define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1\r
322\r
2dbcb8f0 323#endif\r
2ef2b01e
A
324\r
325#endif\r