1#include <common.h>
2#include <exports.h>
3
4#ifndef GCC_VERSION
5#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
6#endif
7
8#if defined(CONFIG_X86)
9
10
11
12
13
14
15
16static void **jt;
17gd_t *global_data;
18
19#define EXPORT_FUNC(x) \
20 asm volatile ( \
21" .globl " #x "\n" \
22#x ":\n" \
23" movl %0, %%eax\n" \
24" movl jt, %%ecx\n" \
25" jmp *(%%ecx, %%eax)\n" \
26 : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
27#elif defined(CONFIG_PPC)
28
29
30
31
32#define EXPORT_FUNC(x) \
33 asm volatile ( \
34" .globl " #x "\n" \
35#x ":\n" \
36" lwz %%r11, %0(%%r2)\n" \
37" lwz %%r11, %1(%%r11)\n" \
38" mtctr %%r11\n" \
39" bctr\n" \
40 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11");
41#elif defined(CONFIG_ARM)
42
43
44
45
46#define EXPORT_FUNC(x) \
47 asm volatile ( \
48" .globl " #x "\n" \
49#x ":\n" \
50" ldr ip, [r8, %0]\n" \
51" ldr pc, [ip, %1]\n" \
52 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip");
53#elif defined(CONFIG_MIPS)
54
55
56
57
58
59
60
61#define EXPORT_FUNC(x) \
62 asm volatile ( \
63" .globl " #x "\n" \
64#x ":\n" \
65" lw $25, %0($26)\n" \
66" lw $25, %1($25)\n" \
67" jr $25\n" \
68 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
69#elif defined(CONFIG_NIOS2)
70
71
72
73#define EXPORT_FUNC(x) \
74 asm volatile ( \
75" .globl " #x "\n" \
76#x ":\n" \
77" movhi r8, %%hi(%0)\n" \
78" ori r8, r0, %%lo(%0)\n" \
79" add r8, r8, gp\n" \
80" ldw r8, 0(r8)\n" \
81" ldw r8, %1(r8)\n" \
82" jmp r8\n" \
83 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "gp");
84#elif defined(CONFIG_M68K)
85
86
87
88
89#define EXPORT_FUNC(x) \
90 asm volatile ( \
91" .globl " #x "\n" \
92#x ":\n" \
93" move.l %%d7, %%a0\n" \
94" adda.l %0, %%a0\n" \
95" move.l (%%a0), %%a0\n" \
96" adda.l %1, %%a0\n" \
97" move.l (%%a0), %%a0\n" \
98" jmp (%%a0)\n" \
99 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
100#elif defined(CONFIG_MICROBLAZE)
101
102
103
104#define EXPORT_FUNC(x) \
105 asm volatile ( \
106" .globl " #x "\n" \
107#x ":\n" \
108" lwi r5, r31, %0\n" \
109" lwi r5, r5, %1\n" \
110" bra r5\n" \
111 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
112#elif defined(CONFIG_BLACKFIN)
113
114
115
116
117#define EXPORT_FUNC(x) \
118 asm volatile ( \
119" .globl _" #x "\n_" \
120#x ":\n" \
121" P0 = [P3 + %0]\n" \
122" P0 = [P0 + %1]\n" \
123" JUMP (P0)\n" \
124 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0");
125#elif defined(CONFIG_AVR32)
126
127
128
129#define EXPORT_FUNC(x) \
130 asm volatile( \
131 " .globl\t" #x "\n" \
132 #x ":\n" \
133 " ld.w r8, r6[%0]\n" \
134 " ld.w pc, r8[%1]\n" \
135 : \
136 : "i"(offsetof(gd_t, jt)), "i"(XF_ ##x) \
137 : "r8");
138#elif defined(CONFIG_SH)
139
140
141
142#define EXPORT_FUNC(x) \
143 asm volatile ( \
144 " .align 2\n" \
145 " .globl " #x "\n" \
146 #x ":\n" \
147 " mov r13, r1\n" \
148 " add %0, r1\n" \
149 " mov.l @r1, r2\n" \
150 " add %1, r2\n" \
151 " mov.l @r2, r1\n" \
152 " jmp @r1\n" \
153 " nop\n" \
154 " nop\n" \
155 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1", "r2");
156#elif defined(CONFIG_SPARC)
157
158
159
160#define EXPORT_FUNC(x) \
161 asm volatile( \
162" .globl\t" #x "\n" \
163#x ":\n" \
164" set %0, %%g1\n" \
165" or %%g1, %%g7, %%g1\n" \
166" ld [%%g1], %%g1\n" \
167" ld [%%g1 + %1], %%g1\n" \
168" jmp %%g1\n" \
169" nop\n" \
170 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "g1" );
171#elif defined(CONFIG_NDS32)
172
173
174
175
176#define EXPORT_FUNC(x) \
177 asm volatile ( \
178" .globl " #x "\n" \
179#x ":\n" \
180" lwi $r16, [$gp + (%0)]\n" \
181" lwi $r16, [$r16 + (%1)]\n" \
182" jr $r16\n" \
183 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "$r16");
184#elif defined(CONFIG_OPENRISC)
185
186
187
188
189#define EXPORT_FUNC(x) \
190 asm volatile ( \
191" .globl " #x "\n" \
192#x ":\n" \
193" l.lwz r13, %0(r10)\n" \
194" l.lwz r13, %1(r13)\n" \
195" l.jr r13\n" \
196" l.nop\n" \
197 : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
198#else
199
200
201
202#error stubs definition missing for this architecture
203#endif
204
205
206
207
208
209
210
211
212#if GCC_VERSION < 3004
213static
214#endif
215void __attribute__((unused)) dummy(void)
216{
217#include <_exports.h>
218}
219
220extern unsigned long __bss_start, _end;
221
222void app_startup(char * const *argv)
223{
224 unsigned char * cp = (unsigned char *) &__bss_start;
225
226
227 while (cp < (unsigned char *)&_end) {
228 *cp++ = 0;
229 }
230
231#if defined(CONFIG_X86)
232
233 global_data = (gd_t *)argv[-1];
234 jt = global_data->jt;
235#endif
236}
237
238#undef EXPORT_FUNC
239