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