xref: /rk3399_rockchip-uboot/arch/arm/include/asm/macro.h (revision 0ae7653128c80a4f2920cbe9b124792c2fd9d9e0)
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