123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /** @file
- Macros to work around lack of Apple support for LDR register, =expr
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
- **/
- #ifndef __MACRO_IO_LIB_H__
- #define __MACRO_IO_LIB_H__
- #if defined(__APPLE__)
- //
- // ldr reg, =expr does not work with current Apple tool chain. So do the work our selves
- //
- // returns _Data in R0 and _Address in R1
- #define MmioWrite32(_Address, _Data) \
- ldr r1, [pc, #8] ; \
- ldr r0, [pc, #8] ; \
- str r0, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- .long (_Data) ; \
- 1:
- // returns _Data in R0 and _Address in R1, and _OrData in r2
- #define MmioOr32(_Address, _OrData) \
- ldr r1, [pc, #16] ; \
- ldr r2, [pc, #16] ; \
- ldr r0, [r1] ; \
- orr r0, r0, r2 ; \
- str r0, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- .long (_OrData) ; \
- 1:
- // returns _Data in R0 and _Address in R1, and _OrData in r2
- #define MmioAnd32(_Address, _AndData) \
- ldr r1, [pc, #16] ; \
- ldr r2, [pc, #16] ; \
- ldr r0, [r1] ; \
- and r0, r0, r2 ; \
- str r0, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- .long (_AndData) ; \
- 1:
- // returns result in R0, _Address in R1, and _OrData in r2
- #define MmioAndThenOr32(_Address, _AndData, _OrData) \
- ldr r1, [pc, #24] ; \
- ldr r0, [r1] ; \
- ldr r2, [pc, #20] ; \
- and r0, r0, r2 ; \
- ldr r2, [pc, #16] ; \
- orr r0, r0, r2 ; \
- str r0, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- .long (_AndData) ; \
- .long (_OrData) ; \
- 1:
- // returns _Data in _Reg and _Address in R1
- #define MmioWriteFromReg32(_Address, _Reg) \
- ldr r1, [pc, #4] ; \
- str _Reg, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- 1:
- // returns _Data in R0 and _Address in R1
- #define MmioRead32(_Address) \
- ldr r1, [pc, #4] ; \
- ldr r0, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- 1:
- // returns _Data in Reg and _Address in R1
- #define MmioReadToReg32(_Address, _Reg) \
- ldr r1, [pc, #4] ; \
- ldr _Reg, [r1] ; \
- b 1f ; \
- .long (_Address) ; \
- 1:
- // load R0 with _Data
- #define LoadConstant(_Data) \
- ldr r0, [pc, #0] ; \
- b 1f ; \
- .long (_Data) ; \
- 1:
- // load _Reg with _Data
- #define LoadConstantToReg(_Data, _Reg) \
- ldr _Reg, [pc, #0] ; \
- b 1f ; \
- .long (_Data) ; \
- 1:
- // load _Reg with _Data if eq
- #define LoadConstantToRegIfEq(_Data, _Reg) \
- ldreq _Reg, [pc, #0] ; \
- b 1f ; \
- .long (_Data) ; \
- 1:
- // Reserve a region at the top of the Primary Core stack
- // for Global variables for the XIP phase
- #define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
- and Tmp, GlobalSize, #7 ; \
- rsbne Tmp, Tmp, #8 ; \
- add GlobalSize, GlobalSize, Tmp ; \
- sub sp, StackTop, GlobalSize ; \
- ; \
- mov Tmp, sp ; \
- mov GlobalSize, #0x0 ; \
- _SetPrimaryStackInitGlobals: ; \
- cmp Tmp, StackTop ; \
- beq _SetPrimaryStackEnd ; \
- str GlobalSize, [Tmp], #4 ; \
- b _SetPrimaryStackInitGlobals ; \
- _SetPrimaryStackEnd:
- // Initialize the Global Variable with '0'
- #define InitializePrimaryStack(GlobalSize, Tmp1) \
- and Tmp1, GlobalSize, #7 ; \
- rsbne Tmp1, Tmp1, #8 ; \
- add GlobalSize, GlobalSize, Tmp1 ; \
- ; \
- mov Tmp1, sp ; \
- sub sp, GlobalSize ; \
- mov GlobalSize, #0x0 ; \
- _InitializePrimaryStackLoop: ; \
- cmp Tmp1, sp ; \
- bls _InitializePrimaryStackEnd ; \
- str GlobalSize, [Tmp1], #-4 ; \
- b _InitializePrimaryStackLoop ; \
- _InitializePrimaryStackEnd:
- #elif defined (__GNUC__)
- #define MmioWrite32(Address, Data) \
- ldr r1, =Address ; \
- ldr r0, =Data ; \
- str r0, [r1]
- #define MmioOr32(Address, OrData) \
- ldr r1, =Address ; \
- ldr r2, =OrData ; \
- ldr r0, [r1] ; \
- orr r0, r0, r2 ; \
- str r0, [r1]
- #define MmioAnd32(Address, AndData) \
- ldr r1, =Address ; \
- ldr r2, =AndData ; \
- ldr r0, [r1] ; \
- and r0, r0, r2 ; \
- str r0, [r1]
- #define MmioAndThenOr32(Address, AndData, OrData) \
- ldr r1, =Address ; \
- ldr r0, [r1] ; \
- ldr r2, =AndData ; \
- and r0, r0, r2 ; \
- ldr r2, =OrData ; \
- orr r0, r0, r2 ; \
- str r0, [r1]
- #define MmioWriteFromReg32(Address, Reg) \
- ldr r1, =Address ; \
- str Reg, [r1]
- #define MmioRead32(Address) \
- ldr r1, =Address ; \
- ldr r0, [r1]
- #define MmioReadToReg32(Address, Reg) \
- ldr r1, =Address ; \
- ldr Reg, [r1]
- #define LoadConstant(Data) \
- ldr r0, =Data
- #define LoadConstantToReg(Data, Reg) \
- ldr Reg, =Data
- #define SetPrimaryStack(StackTop, GlobalSize, Tmp) \
- and Tmp, GlobalSize, #7 ; \
- rsbne Tmp, Tmp, #8 ; \
- add GlobalSize, GlobalSize, Tmp ; \
- sub sp, StackTop, GlobalSize ; \
- ; \
- mov Tmp, sp ; \
- mov GlobalSize, #0x0 ; \
- _SetPrimaryStackInitGlobals: ; \
- cmp Tmp, StackTop ; \
- beq _SetPrimaryStackEnd ; \
- str GlobalSize, [Tmp], #4 ; \
- b _SetPrimaryStackInitGlobals ; \
- _SetPrimaryStackEnd:
- // Initialize the Global Variable with '0'
- #define InitializePrimaryStack(GlobalSize, Tmp1) \
- and Tmp1, GlobalSize, #7 ; \
- rsbne Tmp1, Tmp1, #8 ; \
- add GlobalSize, GlobalSize, Tmp1 ; \
- ; \
- mov Tmp1, sp ; \
- sub sp, GlobalSize ; \
- mov GlobalSize, #0x0 ; \
- _InitializePrimaryStackLoop: ; \
- cmp Tmp1, sp ; \
- bls _InitializePrimaryStackEnd ; \
- str GlobalSize, [Tmp1], #-4 ; \
- b _InitializePrimaryStackLoop ; \
- _InitializePrimaryStackEnd:
- #else
- //
- // Use ARM assembly macros, form armasam
- //
- // Less magic in the macros if ldr reg, =expr works
- //
- // returns _Data in R0 and _Address in R1
- #define MmioWrite32(Address, Data) MmioWrite32Macro Address, Data
- // returns Data in R0 and Address in R1, and OrData in r2
- #define MmioOr32(Address, OrData) MmioOr32Macro Address, OrData
- // returns _Data in R0 and _Address in R1, and _OrData in r2
- #define MmioAnd32(Address, AndData) MmioAnd32Macro Address, AndData
- // returns result in R0, _Address in R1, and _OrData in r2
- #define MmioAndThenOr32(Address, AndData, OrData) MmioAndThenOr32Macro Address, AndData, OrData
- // returns _Data in _Reg and _Address in R1
- #define MmioWriteFromReg32(Address, Reg) MmioWriteFromReg32Macro Address, Reg
- // returns _Data in R0 and _Address in R1
- #define MmioRead32(Address) MmioRead32Macro Address
- // returns _Data in Reg and _Address in R1
- #define MmioReadToReg32(Address, Reg) MmioReadToReg32Macro Address, Reg
- // load R0 with _Data
- #define LoadConstant(Data) LoadConstantMacro Data
- // load _Reg with _Data
- #define LoadConstantToReg(Data, Reg) LoadConstantToRegMacro Data, Reg
- // conditional load testing eq flag
- #define LoadConstantToRegIfEq(Data, Reg) LoadConstantToRegIfEqMacro Data, Reg
- #define SetPrimaryStack(StackTop,GlobalSize,Tmp) SetPrimaryStack StackTop, GlobalSize, Tmp
- // Initialize the Global Variable with '0'
- #define InitializePrimaryStack(GlobalSize, Tmp1) InitializePrimaryStack GlobalSize, Tmp1
- #endif
- #endif
|