Sam Ravnborg | a439fe5 | 2008-07-27 23:00:59 +0200 | [diff] [blame] | 1 | /* |
| 2 | * asm/btfixup.h: Macros for boot time linking. |
| 3 | * |
| 4 | * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
| 5 | */ |
| 6 | |
| 7 | #ifndef _SPARC_BTFIXUP_H |
| 8 | #define _SPARC_BTFIXUP_H |
| 9 | |
| 10 | #include <linux/init.h> |
| 11 | |
| 12 | #ifndef __ASSEMBLY__ |
| 13 | |
| 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); |
| 19 | |
| 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 |
| 25 | |
| 26 | #else |
| 27 | |
| 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 */ |
| 35 | |
| 36 | /* Fixup call xx */ |
| 37 | |
| 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 |
| 45 | |
| 46 | #define BTFIXUPDEF_BLACKBOX(__name) \ |
| 47 | extern unsigned ___bs_##__name[2]; |
| 48 | |
| 49 | /* Put bottom 13bits into some register variable */ |
| 50 | |
| 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; \ |
| 58 | } |
| 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; \ |
| 66 | } |
| 67 | |
| 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; ) |
| 71 | */ |
| 72 | |
| 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; \ |
| 80 | } |
| 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; \ |
| 88 | } |
| 89 | |
| 90 | /* Put upper 22 bits into some register variable */ |
| 91 | |
| 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; \ |
| 99 | } |
| 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; \ |
| 108 | } |
| 109 | |
| 110 | /* Put a full 32bit integer into some register variable */ |
| 111 | |
| 112 | #define BTFIXUPDEF_INT(__name) \ |
| 113 | extern unsigned char ___i_##__name; \ |
| 114 | extern unsigned ___is_##__name[2]; |
| 115 | |
| 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] */ |
| 127 | |
| 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) |
| 134 | |
| 135 | #define BTFIXUPSET_BLACKBOX(__name, __func) \ |
| 136 | do { \ |
| 137 | ___bs_##__name[0] |= 1; \ |
| 138 | ___bs_##__name[1] = (unsigned long)__func; \ |
| 139 | } while (0) |
| 140 | |
| 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) |
| 147 | |
| 148 | #define BTFIXUPSET_SIMM13(__name, __val) \ |
| 149 | do { \ |
| 150 | ___ss_##__name[0] |= 1; \ |
| 151 | ___ss_##__name[1] = (unsigned)__val; \ |
| 152 | } while (0) |
| 153 | |
| 154 | #define BTFIXUPCOPY_SIMM13(__name, __from) \ |
| 155 | do { \ |
| 156 | ___ss_##__name[0] |= 1; \ |
| 157 | ___ss_##__name[1] = ___ss_##__from[1]; \ |
| 158 | } while (0) |
| 159 | |
| 160 | #define BTFIXUPSET_HALF(__name, __val) \ |
| 161 | do { \ |
| 162 | ___as_##__name[0] |= 1; \ |
| 163 | ___as_##__name[1] = (unsigned)__val; \ |
| 164 | } while (0) |
| 165 | |
| 166 | #define BTFIXUPCOPY_HALF(__name, __from) \ |
| 167 | do { \ |
| 168 | ___as_##__name[0] |= 1; \ |
| 169 | ___as_##__name[1] = ___as_##__from[1]; \ |
| 170 | } while (0) |
| 171 | |
| 172 | #define BTFIXUPSET_SETHI(__name, __val) \ |
| 173 | do { \ |
| 174 | ___hs_##__name[0] |= 1; \ |
| 175 | ___hs_##__name[1] = (unsigned)__val; \ |
| 176 | } while (0) |
| 177 | |
| 178 | #define BTFIXUPCOPY_SETHI(__name, __from) \ |
| 179 | do { \ |
| 180 | ___hs_##__name[0] |= 1; \ |
| 181 | ___hs_##__name[1] = ___hs_##__from[1]; \ |
| 182 | } while (0) |
| 183 | |
| 184 | #define BTFIXUPSET_INT(__name, __val) \ |
| 185 | do { \ |
| 186 | ___is_##__name[0] |= 1; \ |
| 187 | ___is_##__name[1] = (unsigned)__val; \ |
| 188 | } while (0) |
| 189 | |
| 190 | #define BTFIXUPCOPY_INT(__name, __from) \ |
| 191 | do { \ |
| 192 | ___is_##__name[0] |= 1; \ |
| 193 | ___is_##__name[1] = ___is_##__from[1]; \ |
| 194 | } while (0) |
| 195 | |
| 196 | #define BTFIXUPVAL_CALL(__name) \ |
| 197 | ((unsigned long)___fs_##__name[1]) |
| 198 | |
| 199 | extern void btfixup(void); |
| 200 | |
| 201 | #else /* __ASSEMBLY__ */ |
| 202 | |
| 203 | #define BTFIXUP_SETHI(__name) %hi(___h_ ## __name) |
| 204 | #define BTFIXUP_SETHI_INIT(__name,__val) %hi(___h_ ## __name ## __btset_ ## __val) |
| 205 | |
| 206 | #endif /* __ASSEMBLY__ */ |
| 207 | |
| 208 | #endif /* !(_SPARC_BTFIXUP_H) */ |