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