1819833afSPeter Tyser /* 2819833afSPeter Tyser * include/asm-arm/macro.h 3819833afSPeter Tyser * 4819833afSPeter Tyser * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> 5819833afSPeter Tyser * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 7819833afSPeter Tyser */ 8819833afSPeter Tyser 9819833afSPeter Tyser #ifndef __ASM_ARM_MACRO_H__ 10819833afSPeter Tyser #define __ASM_ARM_MACRO_H__ 11819833afSPeter Tyser #ifdef __ASSEMBLY__ 12819833afSPeter Tyser 13819833afSPeter Tyser /* 14819833afSPeter Tyser * These macros provide a convenient way to write 8, 16 and 32 bit data 15819833afSPeter Tyser * to any address. 16819833afSPeter Tyser * Registers r4 and r5 are used, any data in these registers are 17819833afSPeter Tyser * overwritten by the macros. 18819833afSPeter Tyser * The macros are valid for any ARM architecture, they do not implement 19819833afSPeter Tyser * any memory barriers so caution is recommended when using these when the 20819833afSPeter Tyser * caches are enabled or on a multi-core system. 21819833afSPeter Tyser */ 22819833afSPeter Tyser 23819833afSPeter Tyser .macro write32, addr, data 24819833afSPeter Tyser ldr r4, =\addr 25819833afSPeter Tyser ldr r5, =\data 26819833afSPeter Tyser str r5, [r4] 27819833afSPeter Tyser .endm 28819833afSPeter Tyser 29819833afSPeter Tyser .macro write16, addr, data 30819833afSPeter Tyser ldr r4, =\addr 31819833afSPeter Tyser ldrh r5, =\data 32819833afSPeter Tyser strh r5, [r4] 33819833afSPeter Tyser .endm 34819833afSPeter Tyser 35819833afSPeter Tyser .macro write8, addr, data 36819833afSPeter Tyser ldr r4, =\addr 37819833afSPeter Tyser ldrb r5, =\data 38819833afSPeter Tyser strb r5, [r4] 39819833afSPeter Tyser .endm 40819833afSPeter Tyser 41819833afSPeter Tyser /* 42819833afSPeter Tyser * This macro generates a loop that can be used for delays in the code. 43819833afSPeter Tyser * Register r4 is used, any data in this register is overwritten by the 44819833afSPeter Tyser * macro. 45819833afSPeter Tyser * The macro is valid for any ARM architeture. The actual time spent in the 46819833afSPeter Tyser * loop will vary from CPU to CPU though. 47819833afSPeter Tyser */ 48819833afSPeter Tyser 49819833afSPeter Tyser .macro wait_timer, time 50819833afSPeter Tyser ldr r4, =\time 51819833afSPeter Tyser 1: 52819833afSPeter Tyser nop 53819833afSPeter Tyser subs r4, r4, #1 54819833afSPeter Tyser bcs 1b 55819833afSPeter Tyser .endm 56819833afSPeter Tyser 57*0ae76531SDavid Feng #ifdef CONFIG_ARM64 58*0ae76531SDavid Feng /* 59*0ae76531SDavid Feng * Register aliases. 60*0ae76531SDavid Feng */ 61*0ae76531SDavid Feng lr .req x30 62*0ae76531SDavid Feng 63*0ae76531SDavid Feng /* 64*0ae76531SDavid Feng * Branch according to exception level 65*0ae76531SDavid Feng */ 66*0ae76531SDavid Feng .macro switch_el, xreg, el3_label, el2_label, el1_label 67*0ae76531SDavid Feng mrs \xreg, CurrentEL 68*0ae76531SDavid Feng cmp \xreg, 0xc 69*0ae76531SDavid Feng b.eq \el3_label 70*0ae76531SDavid Feng cmp \xreg, 0x8 71*0ae76531SDavid Feng b.eq \el2_label 72*0ae76531SDavid Feng cmp \xreg, 0x4 73*0ae76531SDavid Feng b.eq \el1_label 74*0ae76531SDavid Feng .endm 75*0ae76531SDavid Feng 76*0ae76531SDavid Feng /* 77*0ae76531SDavid Feng * Branch if current processor is a slave, 78*0ae76531SDavid Feng * choose processor with all zero affinity value as the master. 79*0ae76531SDavid Feng */ 80*0ae76531SDavid Feng .macro branch_if_slave, xreg, slave_label 81*0ae76531SDavid Feng mrs \xreg, mpidr_el1 82*0ae76531SDavid Feng tst \xreg, #0xff /* Test Affinity 0 */ 83*0ae76531SDavid Feng b.ne \slave_label 84*0ae76531SDavid Feng lsr \xreg, \xreg, #8 85*0ae76531SDavid Feng tst \xreg, #0xff /* Test Affinity 1 */ 86*0ae76531SDavid Feng b.ne \slave_label 87*0ae76531SDavid Feng lsr \xreg, \xreg, #8 88*0ae76531SDavid Feng tst \xreg, #0xff /* Test Affinity 2 */ 89*0ae76531SDavid Feng b.ne \slave_label 90*0ae76531SDavid Feng lsr \xreg, \xreg, #16 91*0ae76531SDavid Feng tst \xreg, #0xff /* Test Affinity 3 */ 92*0ae76531SDavid Feng b.ne \slave_label 93*0ae76531SDavid Feng .endm 94*0ae76531SDavid Feng 95*0ae76531SDavid Feng /* 96*0ae76531SDavid Feng * Branch if current processor is a master, 97*0ae76531SDavid Feng * choose processor with all zero affinity value as the master. 98*0ae76531SDavid Feng */ 99*0ae76531SDavid Feng .macro branch_if_master, xreg1, xreg2, master_label 100*0ae76531SDavid Feng mrs \xreg1, mpidr_el1 101*0ae76531SDavid Feng lsr \xreg2, \xreg1, #32 102*0ae76531SDavid Feng lsl \xreg1, \xreg1, #40 103*0ae76531SDavid Feng lsr \xreg1, \xreg1, #40 104*0ae76531SDavid Feng orr \xreg1, \xreg1, \xreg2 105*0ae76531SDavid Feng cbz \xreg1, \master_label 106*0ae76531SDavid Feng .endm 107*0ae76531SDavid Feng 108*0ae76531SDavid Feng #endif /* CONFIG_ARM64 */ 109*0ae76531SDavid Feng 110819833afSPeter Tyser #endif /* __ASSEMBLY__ */ 111819833afSPeter Tyser #endif /* __ASM_ARM_MACRO_H__ */ 112