Merge tag 'v3.3.7' into 3.3/master
[zen-stable.git] / arch / sparc / include / asm / btfixup.h
blob797722cf69f2869943f4d347a4acb6ad9f72bb77
1 /*
2 * asm/btfixup.h: Macros for boot time linking.
4 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
7 #ifndef _SPARC_BTFIXUP_H
8 #define _SPARC_BTFIXUP_H
10 #include <linux/init.h>
12 #ifndef __ASSEMBLY__
14 #ifdef MODULE
15 extern unsigned int ___illegal_use_of_BTFIXUP_SIMM13_in_module(void);
16 extern unsigned int ___illegal_use_of_BTFIXUP_SETHI_in_module(void);
17 extern unsigned int ___illegal_use_of_BTFIXUP_HALF_in_module(void);
18 extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);
20 #define BTFIXUP_SIMM13(__name) ___illegal_use_of_BTFIXUP_SIMM13_in_module()
21 #define BTFIXUP_HALF(__name) ___illegal_use_of_BTFIXUP_HALF_in_module()
22 #define BTFIXUP_SETHI(__name) ___illegal_use_of_BTFIXUP_SETHI_in_module()
23 #define BTFIXUP_INT(__name) ___illegal_use_of_BTFIXUP_INT_in_module()
24 #define BTFIXUP_BLACKBOX(__name) ___illegal_use_of_BTFIXUP_BLACKBOX_in_module
26 #else
28 #define BTFIXUP_SIMM13(__name) ___sf_##__name()
29 #define BTFIXUP_HALF(__name) ___af_##__name()
30 #define BTFIXUP_SETHI(__name) ___hf_##__name()
31 #define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name)
32 /* This must be written in assembly and present in a sethi */
33 #define BTFIXUP_BLACKBOX(__name) ___b_##__name
34 #endif /* MODULE */
36 /* Fixup call xx */
38 #define BTFIXUPDEF_CALL(__type, __name, __args...) \
39 extern __type ___f_##__name(__args); \
40 extern unsigned ___fs_##__name[3];
41 #define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) \
42 extern __type ___f_##__name(__args) __attribute_const__; \
43 extern unsigned ___fs_##__name[3];
44 #define BTFIXUP_CALL(__name) ___f_##__name
46 #define BTFIXUPDEF_BLACKBOX(__name) \
47 extern unsigned ___bs_##__name[2];
49 /* Put bottom 13bits into some register variable */
51 #define BTFIXUPDEF_SIMM13(__name) \
52 static inline unsigned int ___sf_##__name(void) __attribute_const__; \
53 extern unsigned ___ss_##__name[2]; \
54 static inline unsigned int ___sf_##__name(void) { \
55 unsigned int ret; \
56 __asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret)); \
57 return ret; \
59 #define BTFIXUPDEF_SIMM13_INIT(__name,__val) \
60 static inline unsigned int ___sf_##__name(void) __attribute_const__; \
61 extern unsigned ___ss_##__name[2]; \
62 static inline unsigned int ___sf_##__name(void) { \
63 unsigned int ret; \
64 __asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
65 return ret; \
68 /* Put either bottom 13 bits, or upper 22 bits into some register variable
69 * (depending on the value, this will lead into sethi FIX, reg; or
70 * mov FIX, reg; )
73 #define BTFIXUPDEF_HALF(__name) \
74 static inline unsigned int ___af_##__name(void) __attribute_const__; \
75 extern unsigned ___as_##__name[2]; \
76 static inline unsigned int ___af_##__name(void) { \
77 unsigned int ret; \
78 __asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret)); \
79 return ret; \
81 #define BTFIXUPDEF_HALF_INIT(__name,__val) \
82 static inline unsigned int ___af_##__name(void) __attribute_const__; \
83 extern unsigned ___as_##__name[2]; \
84 static inline unsigned int ___af_##__name(void) { \
85 unsigned int ret; \
86 __asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
87 return ret; \
90 /* Put upper 22 bits into some register variable */
92 #define BTFIXUPDEF_SETHI(__name) \
93 static inline unsigned int ___hf_##__name(void) __attribute_const__; \
94 extern unsigned ___hs_##__name[2]; \
95 static inline unsigned int ___hf_##__name(void) { \
96 unsigned int ret; \
97 __asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret)); \
98 return ret; \
100 #define BTFIXUPDEF_SETHI_INIT(__name,__val) \
101 static inline unsigned int ___hf_##__name(void) __attribute_const__; \
102 extern unsigned ___hs_##__name[2]; \
103 static inline unsigned int ___hf_##__name(void) { \
104 unsigned int ret; \
105 __asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : \
106 "=r"(ret)); \
107 return ret; \
110 /* Put a full 32bit integer into some register variable */
112 #define BTFIXUPDEF_INT(__name) \
113 extern unsigned char ___i_##__name; \
114 extern unsigned ___is_##__name[2];
116 #define BTFIXUPCALL_NORM 0x00000000 /* Always call */
117 #define BTFIXUPCALL_NOP 0x01000000 /* Possibly optimize to nop */
118 #define BTFIXUPCALL_RETINT(i) (0x90102000|((i) & 0x1fff)) /* Possibly optimize to mov i, %o0 */
119 #define BTFIXUPCALL_ORINT(i) (0x90122000|((i) & 0x1fff)) /* Possibly optimize to or %o0, i, %o0 */
120 #define BTFIXUPCALL_RETO0 0x01000000 /* Return first parameter, actually a nop */
121 #define BTFIXUPCALL_ANDNINT(i) (0x902a2000|((i) & 0x1fff)) /* Possibly optimize to andn %o0, i, %o0 */
122 #define BTFIXUPCALL_SWAPO0O1 0xd27a0000 /* Possibly optimize to swap [%o0],%o1 */
123 #define BTFIXUPCALL_SWAPO0G0 0xc07a0000 /* Possibly optimize to swap [%o0],%g0 */
124 #define BTFIXUPCALL_SWAPG1G2 0xc4784000 /* Possibly optimize to swap [%g1],%g2 */
125 #define BTFIXUPCALL_STG0O0 0xc0220000 /* Possibly optimize to st %g0,[%o0] */
126 #define BTFIXUPCALL_STO1O0 0xd2220000 /* Possibly optimize to st %o1,[%o0] */
128 #define BTFIXUPSET_CALL(__name, __addr, __insn) \
129 do { \
130 ___fs_##__name[0] |= 1; \
131 ___fs_##__name[1] = (unsigned long)__addr; \
132 ___fs_##__name[2] = __insn; \
133 } while (0)
135 #define BTFIXUPSET_BLACKBOX(__name, __func) \
136 do { \
137 ___bs_##__name[0] |= 1; \
138 ___bs_##__name[1] = (unsigned long)__func; \
139 } while (0)
141 #define BTFIXUPCOPY_CALL(__name, __from) \
142 do { \
143 ___fs_##__name[0] |= 1; \
144 ___fs_##__name[1] = ___fs_##__from[1]; \
145 ___fs_##__name[2] = ___fs_##__from[2]; \
146 } while (0)
148 #define BTFIXUPSET_SIMM13(__name, __val) \
149 do { \
150 ___ss_##__name[0] |= 1; \
151 ___ss_##__name[1] = (unsigned)__val; \
152 } while (0)
154 #define BTFIXUPCOPY_SIMM13(__name, __from) \
155 do { \
156 ___ss_##__name[0] |= 1; \
157 ___ss_##__name[1] = ___ss_##__from[1]; \
158 } while (0)
160 #define BTFIXUPSET_HALF(__name, __val) \
161 do { \
162 ___as_##__name[0] |= 1; \
163 ___as_##__name[1] = (unsigned)__val; \
164 } while (0)
166 #define BTFIXUPCOPY_HALF(__name, __from) \
167 do { \
168 ___as_##__name[0] |= 1; \
169 ___as_##__name[1] = ___as_##__from[1]; \
170 } while (0)
172 #define BTFIXUPSET_SETHI(__name, __val) \
173 do { \
174 ___hs_##__name[0] |= 1; \
175 ___hs_##__name[1] = (unsigned)__val; \
176 } while (0)
178 #define BTFIXUPCOPY_SETHI(__name, __from) \
179 do { \
180 ___hs_##__name[0] |= 1; \
181 ___hs_##__name[1] = ___hs_##__from[1]; \
182 } while (0)
184 #define BTFIXUPSET_INT(__name, __val) \
185 do { \
186 ___is_##__name[0] |= 1; \
187 ___is_##__name[1] = (unsigned)__val; \
188 } while (0)
190 #define BTFIXUPCOPY_INT(__name, __from) \
191 do { \
192 ___is_##__name[0] |= 1; \
193 ___is_##__name[1] = ___is_##__from[1]; \
194 } while (0)
196 #define BTFIXUPVAL_CALL(__name) \
197 ((unsigned long)___fs_##__name[1])
199 extern void btfixup(void);
201 #else /* __ASSEMBLY__ */
203 #define BTFIXUP_SETHI(__name) %hi(___h_ ## __name)
204 #define BTFIXUP_SETHI_INIT(__name,__val) %hi(___h_ ## __name ## __btset_ ## __val)
206 #endif /* __ASSEMBLY__ */
208 #endif /* !(_SPARC_BTFIXUP_H) */