~ubuntu-branches/ubuntu/maverick/uboot-imx/maverick

« back to all changes in this revision

Viewing changes to examples/standalone/stubs.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-01-20 15:41:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100120154126-7bha1jeyjegu7xm5
Tags: 2009.08+really2009.01-0ubuntu1
* revert to the 2009.01 upstream version, 2009.08 has still to 
  many work in progress items in the freescale patchset (MMC and NIC
  dont work at all)
* add the latest patchset from freescale for 2009.01
* add 1002_enable_hush_shell_and_ext2.patch to enable hush shell and ext2 
* add 1003_fix_board_revision_numbers to make sure babbage 2.5 boards have 
  revision 51120 and babbage 3.0 boards have revision 51130 properly set in 
  their cpuinfo

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <exports.h>
2
 
 
3
 
#ifndef GCC_VERSION
4
 
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
5
 
#endif /* GCC_VERSION */
6
 
 
7
 
#if defined(CONFIG_I386)
8
 
/*
9
 
 * x86 does not have a dedicated register to store the pointer to
10
 
 * the global_data. Thus the jump table address is stored in a
11
 
 * global variable, but such approach does not allow for execution
12
 
 * from flash memory. The global_data address is passed as argv[-1]
13
 
 * to the application program.
14
 
 */
15
 
static void **jt;
16
 
gd_t *global_data;
17
 
 
18
 
#define EXPORT_FUNC(x) \
19
 
        asm volatile (                  \
20
 
"       .globl " #x "\n"                \
21
 
#x ":\n"                                \
22
 
"       movl    %0, %%eax\n"            \
23
 
"       movl    jt, %%ecx\n"            \
24
 
"       jmp     *(%%ecx, %%eax)\n"      \
25
 
        : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
26
 
#elif defined(CONFIG_PPC)
27
 
/*
28
 
 * r2 holds the pointer to the global_data, r11 is a call-clobbered
29
 
 * register
30
 
 */
31
 
#define EXPORT_FUNC(x) \
32
 
        asm volatile (                  \
33
 
"       .globl " #x "\n"                \
34
 
#x ":\n"                                \
35
 
"       lwz     %%r11, %0(%%r2)\n"      \
36
 
"       lwz     %%r11, %1(%%r11)\n"     \
37
 
"       mtctr   %%r11\n"                \
38
 
"       bctr\n"                         \
39
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11");
40
 
#elif defined(CONFIG_ARM)
41
 
/*
42
 
 * r8 holds the pointer to the global_data, ip is a call-clobbered
43
 
 * register
44
 
 */
45
 
#define EXPORT_FUNC(x) \
46
 
        asm volatile (                  \
47
 
"       .globl " #x "\n"                \
48
 
#x ":\n"                                \
49
 
"       ldr     ip, [r8, %0]\n"         \
50
 
"       ldr     pc, [ip, %1]\n"         \
51
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip");
52
 
#elif defined(CONFIG_MIPS)
53
 
/*
54
 
 * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
55
 
 * clobbered register that is also used to set gp ($26). Note that the
56
 
 * jr instruction also executes the instruction immediately following
57
 
 * it; however, GCC/mips generates an additional `nop' after each asm
58
 
 * statement
59
 
 */
60
 
#define EXPORT_FUNC(x) \
61
 
        asm volatile (                  \
62
 
"       .globl " #x "\n"                \
63
 
#x ":\n"                                \
64
 
"       lw      $25, %0($26)\n"         \
65
 
"       lw      $25, %1($25)\n"         \
66
 
"       jr      $25\n"                  \
67
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
68
 
#elif defined(CONFIG_NIOS)
69
 
/*
70
 
 * %g7 holds the pointer to the global_data. %g0 is call clobbered.
71
 
 */
72
 
#define EXPORT_FUNC(x) \
73
 
        asm volatile (                  \
74
 
"       .globl " #x "\n"                \
75
 
#x ":\n"                                \
76
 
"       pfx     %%hi(%0)\n"             \
77
 
"       movi    %%g0, %%lo(%0)\n"       \
78
 
"       add     %%g0, %%g7\n"           \
79
 
"       ld      %%g0, [%%g0]\n"         \
80
 
"       pfx     %1\n"                   \
81
 
"       ld      %%g0, [%%g0]\n"         \
82
 
"       jmp     %%g0\n"                 \
83
 
"       nop     \n"                     \
84
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x) : "r0");
85
 
#elif defined(CONFIG_NIOS2)
86
 
/*
87
 
 * r15 holds the pointer to the global_data, r8 is call-clobbered
88
 
 */
89
 
#define EXPORT_FUNC(x) \
90
 
        asm volatile (                  \
91
 
"       .globl " #x "\n"                \
92
 
#x ":\n"                                \
93
 
"       movhi   r8, %%hi(%0)\n"         \
94
 
"       ori     r8, r0, %%lo(%0)\n"     \
95
 
"       add     r8, r8, r15\n"          \
96
 
"       ldw     r8, 0(r8)\n"            \
97
 
"       ldw     r8, %1(r8)\n"           \
98
 
"       jmp     r8\n"                   \
99
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r15");
100
 
#elif defined(CONFIG_M68K)
101
 
/*
102
 
 * d7 holds the pointer to the global_data, a0 is a call-clobbered
103
 
 * register
104
 
 */
105
 
#define EXPORT_FUNC(x) \
106
 
        asm volatile (                  \
107
 
"       .globl " #x "\n"                \
108
 
#x ":\n"                                \
109
 
"       move.l  %%d7, %%a0\n"           \
110
 
"       adda.l  %0, %%a0\n"             \
111
 
"       move.l  (%%a0), %%a0\n"         \
112
 
"       adda.l  %1, %%a0\n"             \
113
 
"       move.l  (%%a0), %%a0\n"         \
114
 
"       jmp     (%%a0)\n"                       \
115
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
116
 
#elif defined(CONFIG_MICROBLAZE)
117
 
/*
118
 
 * r31 holds the pointer to the global_data. r5 is a call-clobbered.
119
 
 */
120
 
#define EXPORT_FUNC(x)                          \
121
 
        asm volatile (                          \
122
 
"       .globl " #x "\n"                        \
123
 
#x ":\n"                                        \
124
 
"       lwi     r5, r31, %0\n"                  \
125
 
"       lwi     r5, r5, %1\n"                   \
126
 
"       bra     r5\n"                           \
127
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
128
 
#elif defined(CONFIG_BLACKFIN)
129
 
/*
130
 
 * P5 holds the pointer to the global_data, P0 is a call-clobbered
131
 
 * register
132
 
 */
133
 
#define EXPORT_FUNC(x)                  \
134
 
        asm volatile (                  \
135
 
"       .globl _" #x "\n_"              \
136
 
#x ":\n"                                \
137
 
"       P0 = [P5 + %0]\n"               \
138
 
"       P0 = [P0 + %1]\n"               \
139
 
"       JUMP (P0)\n"                    \
140
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0");
141
 
#elif defined(CONFIG_AVR32)
142
 
/*
143
 
 * r6 holds the pointer to the global_data. r8 is call clobbered.
144
 
 */
145
 
#define EXPORT_FUNC(x)                                  \
146
 
        asm volatile(                                   \
147
 
                "       .globl\t" #x "\n"               \
148
 
                #x ":\n"                                \
149
 
                "       ld.w    r8, r6[%0]\n"           \
150
 
                "       ld.w    pc, r8[%1]\n"           \
151
 
                :                                       \
152
 
                : "i"(offsetof(gd_t, jt)), "i"(XF_ ##x) \
153
 
                : "r8");
154
 
#elif defined(CONFIG_SH)
155
 
/*
156
 
 * r13 holds the pointer to the global_data. r1 is a call clobbered.
157
 
 */
158
 
#define EXPORT_FUNC(x)                                  \
159
 
        asm volatile (                                  \
160
 
                "       .align  2\n"                    \
161
 
                "       .globl " #x "\n"                \
162
 
                #x ":\n"                                \
163
 
                "       mov     r13, r1\n"              \
164
 
                "       add     %0, r1\n"               \
165
 
                "       mov.l @r1, r2\n"        \
166
 
                "       add     %1, r2\n"               \
167
 
                "       mov.l @r2, r1\n"        \
168
 
                "       jmp     @r1\n"                  \
169
 
                "       nop\n"                          \
170
 
                "       nop\n"                          \
171
 
                : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1", "r2");
172
 
#elif defined(CONFIG_SPARC)
173
 
/*
174
 
 * g7 holds the pointer to the global_data. g1 is call clobbered.
175
 
 */
176
 
#define EXPORT_FUNC(x)                                  \
177
 
        asm volatile(                                   \
178
 
"       .globl\t" #x "\n"                               \
179
 
#x ":\n"                                                \
180
 
"       set %0, %%g1\n"                                 \
181
 
"       or %%g1, %%g7, %%g1\n"                          \
182
 
"       ld [%%g1], %%g1\n"                              \
183
 
"       ld [%%g1 + %1], %%g1\n"                         \
184
 
"       call %%g1\n"                                    \
185
 
"       nop\n"                                          \
186
 
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x) : "g1" );
187
 
 
188
 
#else
189
 
#error stubs definition missing for this architecture
190
 
#endif
191
 
 
192
 
/* This function is necessary to prevent the compiler from
193
 
 * generating prologue/epilogue, preparing stack frame etc.
194
 
 * The stub functions are special, they do not use the stack
195
 
 * frame passed to them, but pass it intact to the actual
196
 
 * implementation. On the other hand, asm() statements with
197
 
 * arguments can be used only inside the functions (gcc limitation)
198
 
 */
199
 
#if GCC_VERSION < 3004
200
 
static
201
 
#endif /* GCC_VERSION */
202
 
void __attribute__((unused)) dummy(void)
203
 
{
204
 
#include <_exports.h>
205
 
}
206
 
 
207
 
extern unsigned long __bss_start, _end;
208
 
 
209
 
void app_startup(char **argv)
210
 
{
211
 
        unsigned char * cp = (unsigned char *) &__bss_start;
212
 
 
213
 
        /* Zero out BSS */
214
 
        while (cp < (unsigned char *)&_end) {
215
 
                *cp++ = 0;
216
 
        }
217
 
 
218
 
#if defined(CONFIG_I386)
219
 
        /* x86 does not have a dedicated register for passing global_data */
220
 
        global_data = (gd_t *)argv[-1];
221
 
        jt = global_data->jt;
222
 
#endif
223
 
}
224
 
 
225
 
#undef EXPORT_FUNC