btfixup.h 7.1 KB
Newer Older
A
Adrian Bunk 已提交
1
/*
2
 *  asm/btfixup.h:    Macros for boot time linking.
L
Linus Torvalds 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
 *
 *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 */
 
#ifndef _SPARC_BTFIXUP_H
#define _SPARC_BTFIXUP_H

#include <linux/init.h>

#ifndef __ASSEMBLY__

#ifdef MODULE
extern unsigned int ___illegal_use_of_BTFIXUP_SIMM13_in_module(void);
extern unsigned int ___illegal_use_of_BTFIXUP_SETHI_in_module(void);
extern unsigned int ___illegal_use_of_BTFIXUP_HALF_in_module(void);
extern unsigned int ___illegal_use_of_BTFIXUP_INT_in_module(void);

#define BTFIXUP_SIMM13(__name) ___illegal_use_of_BTFIXUP_SIMM13_in_module()
#define BTFIXUP_HALF(__name) ___illegal_use_of_BTFIXUP_HALF_in_module()
#define BTFIXUP_SETHI(__name) ___illegal_use_of_BTFIXUP_SETHI_in_module()
#define BTFIXUP_INT(__name) ___illegal_use_of_BTFIXUP_INT_in_module()
#define BTFIXUP_BLACKBOX(__name) ___illegal_use_of_BTFIXUP_BLACKBOX_in_module

#else

#define BTFIXUP_SIMM13(__name) ___sf_##__name()
#define BTFIXUP_HALF(__name) ___af_##__name()
#define BTFIXUP_SETHI(__name) ___hf_##__name()
#define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name)
/* This must be written in assembly and present in a sethi */
#define BTFIXUP_BLACKBOX(__name) ___b_##__name
#endif /* MODULE */

/* Fixup call xx */

#define BTFIXUPDEF_CALL(__type, __name, __args...) 					\
	extern __type ___f_##__name(__args);						\
	extern unsigned ___fs_##__name[3];
#define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) 				\
	extern __type ___f_##__name(__args) __attribute_const__;			\
	extern unsigned ___fs_##__name[3];
#define BTFIXUP_CALL(__name) ___f_##__name

#define BTFIXUPDEF_BLACKBOX(__name)							\
	extern unsigned ___bs_##__name[2];

/* Put bottom 13bits into some register variable */

#define BTFIXUPDEF_SIMM13(__name)							\
52
	static inline unsigned int ___sf_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
53
	extern unsigned ___ss_##__name[2];						\
54
	static inline unsigned int ___sf_##__name(void) {				\
L
Linus Torvalds 已提交
55 56 57 58 59
		unsigned int ret;							\
		__asm__ ("or %%g0, ___s_" #__name ", %0" : "=r"(ret));			\
		return ret;								\
	}
#define BTFIXUPDEF_SIMM13_INIT(__name,__val)						\
60
	static inline unsigned int ___sf_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
61
	extern unsigned ___ss_##__name[2];						\
62
	static inline unsigned int ___sf_##__name(void) {				\
L
Linus Torvalds 已提交
63 64 65 66 67 68 69 70 71 72 73
		unsigned int ret;							\
		__asm__ ("or %%g0, ___s_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
		return ret;								\
	}

/* Put either bottom 13 bits, or upper 22 bits into some register variable
 * (depending on the value, this will lead into sethi FIX, reg; or
 * mov FIX, reg; )
 */

#define BTFIXUPDEF_HALF(__name)								\
74
	static inline unsigned int ___af_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
75
	extern unsigned ___as_##__name[2];						\
76
	static inline unsigned int ___af_##__name(void) {				\
L
Linus Torvalds 已提交
77 78 79 80 81
		unsigned int ret;							\
		__asm__ ("or %%g0, ___a_" #__name ", %0" : "=r"(ret));			\
		return ret;								\
	}
#define BTFIXUPDEF_HALF_INIT(__name,__val)						\
82
	static inline unsigned int ___af_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
83
	extern unsigned ___as_##__name[2];						\
84
	static inline unsigned int ___af_##__name(void) {				\
L
Linus Torvalds 已提交
85 86 87 88 89 90 91 92
		unsigned int ret;							\
		__asm__ ("or %%g0, ___a_" #__name "__btset_" #__val ", %0" : "=r"(ret));\
		return ret;								\
	}

/* Put upper 22 bits into some register variable */

#define BTFIXUPDEF_SETHI(__name)							\
93
	static inline unsigned int ___hf_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
94
	extern unsigned ___hs_##__name[2];						\
95
	static inline unsigned int ___hf_##__name(void) {				\
L
Linus Torvalds 已提交
96 97 98 99 100
		unsigned int ret;							\
		__asm__ ("sethi %%hi(___h_" #__name "), %0" : "=r"(ret));		\
		return ret;								\
	}
#define BTFIXUPDEF_SETHI_INIT(__name,__val)						\
101
	static inline unsigned int ___hf_##__name(void) __attribute_const__;		\
L
Linus Torvalds 已提交
102
	extern unsigned ___hs_##__name[2];						\
103
	static inline unsigned int ___hf_##__name(void) {				\
L
Linus Torvalds 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
		unsigned int ret;							\
		__asm__ ("sethi %%hi(___h_" #__name "__btset_" #__val "), %0" : 	\
			 "=r"(ret));							\
		return ret;								\
	}

/* Put a full 32bit integer into some register variable */

#define BTFIXUPDEF_INT(__name)								\
	extern unsigned char ___i_##__name;						\
	extern unsigned ___is_##__name[2];

#define BTFIXUPCALL_NORM	0x00000000			/* Always call */
#define BTFIXUPCALL_NOP		0x01000000			/* Possibly optimize to nop */
#define BTFIXUPCALL_RETINT(i)	(0x90102000|((i) & 0x1fff))	/* Possibly optimize to mov i, %o0 */
#define BTFIXUPCALL_ORINT(i)	(0x90122000|((i) & 0x1fff))	/* Possibly optimize to or %o0, i, %o0 */
#define BTFIXUPCALL_RETO0	0x01000000			/* Return first parameter, actually a nop */
#define BTFIXUPCALL_ANDNINT(i)	(0x902a2000|((i) & 0x1fff))	/* Possibly optimize to andn %o0, i, %o0 */
#define BTFIXUPCALL_SWAPO0O1	0xd27a0000			/* Possibly optimize to swap [%o0],%o1 */
#define BTFIXUPCALL_SWAPO0G0	0xc07a0000			/* Possibly optimize to swap [%o0],%g0 */
#define BTFIXUPCALL_SWAPG1G2	0xc4784000			/* Possibly optimize to swap [%g1],%g2 */
#define BTFIXUPCALL_STG0O0	0xc0220000			/* Possibly optimize to st %g0,[%o0] */
#define BTFIXUPCALL_STO1O0	0xd2220000			/* Possibly optimize to st %o1,[%o0] */

#define BTFIXUPSET_CALL(__name, __addr, __insn)						\
	do {										\
		___fs_##__name[0] |= 1;							\
		___fs_##__name[1] = (unsigned long)__addr;				\
		___fs_##__name[2] = __insn;						\
	} while (0)
	
#define BTFIXUPSET_BLACKBOX(__name, __func)						\
	do {										\
		___bs_##__name[0] |= 1;							\
		___bs_##__name[1] = (unsigned long)__func;				\
	} while (0)
	
#define BTFIXUPCOPY_CALL(__name, __from)						\
	do {										\
		___fs_##__name[0] |= 1;							\
		___fs_##__name[1] = ___fs_##__from[1];					\
		___fs_##__name[2] = ___fs_##__from[2];					\
	} while (0)
		
#define BTFIXUPSET_SIMM13(__name, __val)						\
	do {										\
		___ss_##__name[0] |= 1;							\
		___ss_##__name[1] = (unsigned)__val;					\
	} while (0)
	
#define BTFIXUPCOPY_SIMM13(__name, __from)						\
	do {										\
		___ss_##__name[0] |= 1;							\
		___ss_##__name[1] = ___ss_##__from[1];					\
	} while (0)
		
#define BTFIXUPSET_HALF(__name, __val)							\
	do {										\
		___as_##__name[0] |= 1;							\
		___as_##__name[1] = (unsigned)__val;					\
	} while (0)
	
#define BTFIXUPCOPY_HALF(__name, __from)						\
	do {										\
		___as_##__name[0] |= 1;							\
		___as_##__name[1] = ___as_##__from[1];					\
	} while (0)
		
#define BTFIXUPSET_SETHI(__name, __val)							\
	do {										\
		___hs_##__name[0] |= 1;							\
		___hs_##__name[1] = (unsigned)__val;					\
	} while (0)
	
#define BTFIXUPCOPY_SETHI(__name, __from)						\
	do {										\
		___hs_##__name[0] |= 1;							\
		___hs_##__name[1] = ___hs_##__from[1];					\
	} while (0)
		
#define BTFIXUPSET_INT(__name, __val)							\
	do {										\
		___is_##__name[0] |= 1;							\
		___is_##__name[1] = (unsigned)__val;					\
	} while (0)
	
#define BTFIXUPCOPY_INT(__name, __from)							\
	do {										\
		___is_##__name[0] |= 1;							\
		___is_##__name[1] = ___is_##__from[1];					\
	} while (0)
	
#define BTFIXUPVAL_CALL(__name)								\
	((unsigned long)___fs_##__name[1])
	
extern void btfixup(void);

#else /* __ASSEMBLY__ */

#define BTFIXUP_SETHI(__name)			%hi(___h_ ## __name)
#define BTFIXUP_SETHI_INIT(__name,__val)	%hi(___h_ ## __name ## __btset_ ## __val)

#endif /* __ASSEMBLY__ */
	
#endif /* !(_SPARC_BTFIXUP_H) */