]> git.sur5r.net Git - u-boot/blobdiff - examples/stubs.c
VoiceBlue update: eeprom tool can also store firmware version now.
[u-boot] / examples / stubs.c
index c0ef65048e92a82d53bbe2dc0d395b43b1f47457..d4c6e063e3ed1428f0eb4d7a84710b4496e6e34e 100644 (file)
@@ -1,5 +1,9 @@
 #include <exports.h>
 
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif /* GCC_VERSION */
+
 #if defined(CONFIG_I386)
 /*
  * x86 does not have a dedicated register to store the pointer to
@@ -9,6 +13,7 @@
  * to the application program.
  */
 static void **jt;
+gd_t *global_data;
 
 #define EXPORT_FUNC(x) \
        asm volatile (                  \
@@ -60,6 +65,66 @@ static void **jt;
 "      lw      $25, %1($25)\n"         \
 "      jr      $25\n"                  \
        : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
+#elif defined(CONFIG_NIOS)
+/*
+ * %g7 holds the pointer to the global_data. %g0 is call clobbered.
+ */
+#define EXPORT_FUNC(x) \
+       asm volatile (                  \
+"      .globl " #x "\n"                \
+#x ":\n"                               \
+"      pfx     %%hi(%0)\n"             \
+"      movi    %%g0, %%lo(%0)\n"       \
+"      add     %%g0, %%g7\n"           \
+"      ld      %%g0, [%%g0]\n"         \
+"      pfx     %1\n"                   \
+"      ld      %%g0, [%%g0]\n"         \
+"      jmp     %%g0\n"                 \
+"      nop     \n"                     \
+       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x) : "r0");
+#elif defined(CONFIG_NIOS2)
+/*
+ * r15 holds the pointer to the global_data, r8 is call-clobbered
+ */
+#define EXPORT_FUNC(x) \
+       asm volatile (                  \
+"      .globl " #x "\n"                \
+#x ":\n"                               \
+"      movhi   r8, %%hi(%0)\n"         \
+"      ori     r8, r0, %%lo(%0)\n"     \
+"      add     r8, r0, r15\n"          \
+"      ldw     r8, 0(r8)\n"            \
+"      ldw     r8, %1(r8)\n"           \
+"      jmp     r8\n"                   \
+       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r15");
+#elif defined(CONFIG_M68K)
+/*
+ * d7 holds the pointer to the global_data, a0 is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(x) \
+       asm volatile (                  \
+"      .globl " #x "\n"                \
+#x ":\n"                               \
+"      move.l  %%d7, %%a0\n"           \
+"      adda.l  %0, %%a0\n"             \
+"      move.l  (%%a0), %%a0\n"         \
+"      adda.l  %1, %%a0\n"             \
+"      move.l  (%%a0), %%a0\n"         \
+"      jmp     (%%a0)\n"                       \
+       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
+#elif defined(CONFIG_MICROBLAZE)
+/*
+ * r31 holds the pointer to the global_data. r5 is a call-clobbered.
+ */
+#define EXPORT_FUNC(x)                         \
+       asm volatile (                          \
+"      .globl " #x "\n"                        \
+#x ":\n"                                       \
+"      lwi     r5, r31, %0\n"                  \
+"      lwi     r5, r5, %1\n"                   \
+"      bra     r5\n"                           \
+       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
 #else
 #error stubs definition missing for this architecture
 #endif
@@ -71,16 +136,29 @@ static void **jt;
  * implementation. On the other hand, asm() statements with
  * arguments can be used only inside the functions (gcc limitation)
  */
-static void __attribute__((unused)) dummy(void)
+#if GCC_VERSION < 3004
+static
+#endif /* GCC_VERSION */
+void __attribute__((unused)) dummy(void)
 {
 #include <_exports.h>
 }
 
+extern unsigned long __bss_start, _end;
+
 void app_startup(char **argv)
 {
+       unsigned long * cp = &__bss_start;
+
+       /* Zero out BSS */
+       while (cp < &_end) {
+               *cp++ = 0;
+       }
+
 #if defined(CONFIG_I386)
        /* x86 does not have a dedicated register for passing global_data */
-       jt = ((gd_t *)argv[-1])->jt;
+       global_data = (gd_t *)argv[-1];
+       jt = global_data->jt;
 #endif
 }