move sboot to the root directory
[open-ath9k-htc-firmware.git] / sboot / magpie_1_1 / sboot / athos / src / xtos / crt1-sim.S
diff --git a/sboot/magpie_1_1/sboot/athos/src/xtos/crt1-sim.S b/sboot/magpie_1_1/sboot/athos/src/xtos/crt1-sim.S
new file mode 100755 (executable)
index 0000000..5615931
--- /dev/null
@@ -0,0 +1,246 @@
+// crt1-sim.S
+// For the Xtensa simulator target, this code sets up the C calling context
+// and calls main()  (via __clibrary_start).
+// Control arrives here at _start from the reset vector or from crt0-app.S.
+
+// Copyright (c) 1998-2010 Tensilica Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <xtensa/simboard.h>
+#include <xtensa/simcall.h>
+#include <xtensa/coreasm.h>
+#include "xtos-internal.h"
+
+
+// Exports
+.global _start
+
+// Imports
+//   __clibrary_init   from C library (eg. newlib or uclibc)
+//   exit              from C library
+//   main              from user application
+//   __stack           from linker script (see LSP Ref Manual)
+
+.type  __clibrary_init, @function
+.type  main, @function
+.type  exit, @function
+
+
+// Macros to abstract away ABI differences
+
+#if __XTENSA_CALL0_ABI__
+# define CALL  call0
+# define ARG1  a2      /* 1st outgoing call argument */
+# define ARG2  a3      /* 2nd outgoing call argument */
+# define ARG3  a4      /* 3rd outgoing call argument */
+# define ARG4  a5      /* 4th outgoing call argument */
+# define ARG5  a6      /* 5th outgoing call argument */
+#else
+# define CALL  call4
+# define ARG1  a6      /* 1st outgoing call argument */
+# define ARG2  a7      /* 2nd outgoing call argument */
+# define ARG3  a8      /* 3rd outgoing call argument */
+# define ARG4  a9      /* 4th outgoing call argument */
+# define ARG5  a10     /* 5th outgoing call argument */
+#endif
+
+               .data
+               .weak   _start_envp     // allow overriding
+               .align  4
+_start_envp:   .word   0               // empty environ
+
+
+
+       .text
+       .align 4
+
+_start:
+       //  _start is typically NOT at the beginning of the text segment --
+       //  it is always called from either the reset vector or other code
+       //  that does equivalent initialization (such as crt0-app.S).
+       //
+       //  Assumptions on entry to _start:
+       //      - low (level-one) and medium priority interrupts are disabled
+       //        via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
+       //        be zeroed, to potentially enable them, before calling main)
+       //      - C calling context not initialized:
+       //        - PS not initialized
+       //        - SP not initialized
+       //      - the following are initialized:
+       //        - LITBASE, cache attributes, WindowBase, WindowStart,
+       //          CPENABLE, FP's FCR and FSR, EXCSAVE[n]
+
+       // Keep a0 zero.  It is used to initialize a few things.
+       // It is also the return address, where zero indicates
+       // that the frame used by _start is the bottommost frame.
+       //
+       movi    a0, 0           // keep this register zero.
+
+#if XTOS_RESET_UNNEEDED
+#include "reset-unneeded.S"
+#endif
+
+
+       // Initialize the stack pointer.
+       // See the "ABI and Software Conventions" chapter in the
+       // Xtensa ISA Reference manual for details.
+
+       // NOTE: Because the _start routine does not use any memory in its
+       // stack frame, and because all of its CALL instructions use a
+       // window size of 4, the stack frame for _start can be empty.
+       movi    sp, __stack
+
+       // reserve stack space for
+       //    - argv array
+       //    - argument strings
+       movi    a2, SYS_iss_argv_size
+       simcall         // returns size of argv[] + its strings in a2
+#if XCHAL_HAVE_PIF
+       // The stack only needs 16-byte alignment.
+       // However, here we round up the argv size further to 128 byte multiples
+       // so that in most cases, variations in argv[0]'s path do not result in
+       // different stack allocation.  Otherwise, such variations can impact
+       // execution timing (eg. due to cache effects etc) for the same code and data.
+       // If we have a PIF, it's more likely the extra required space is okay.
+       addi    a2, a2, 127
+       srli    a2, a2, 7
+       slli    a2, a2, 7
+#else
+       // Keep stack 16-byte aligned.
+       addi    a2, a2, 15
+       srli    a2, a2, 4
+       slli    a2, a2, 4
+#endif
+       // No need to use MOVSP because we have no caller (we're the
+       // base caller); in fact it's better not to use MOVSP in this
+       // context, to avoid unnecessary ALLOCA exceptions and copying
+       // from undefined memory:
+       //   sub     a3, sp, a2
+       //   movsp   sp, a3
+       sub     sp, sp, a2
+
+
+       /*
+        *  Now that sp (a1) is set, we can set PS as per the application
+        *  (user vector mode, enable interrupts, enable window exceptions if applicable).
+        */
+#if XCHAL_HAVE_EXCEPTIONS
+# ifdef __XTENSA_CALL0_ABI__
+       movi    a3, PS_UM               // PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
+# else  
+       movi    a3, PS_UM|PS_WOE        // PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0
+# endif
+       wsr     a3, PS
+       rsync
+#endif
+
+
+       /*  The new ISS simcall only appeared after RB-2007.2:  */
+#if !XCHAL_HAVE_BOOTLOADER && (XCHAL_HW_MAX_VERSION > XTENSA_HWVERSION_RB_2007_2)      /* pre-LX2 cores only */
+       /*
+        *  Clear the BSS (uninitialized data) segments.
+        *  This code supports multiple zeroed sections (*.bss).
+        *  For speed, we clear memory using an ISS simcall
+        *  (see crt1-boards.S for more generic BSS clearing code).
+        */
+       movi    a6, _bss_table_start
+       movi    a7, _bss_table_end
+       bgeu    a6, a7, .Lnobss
+.Lbssloop:
+       movi    a2, SYS_memset
+       l32i    a3, a6, 0       // arg1 = fill start address
+       movi    a4, 0           // arg2 = fill pattern
+       l32i    a5, a6, 4       // get end address
+       addi    a6, a6, 8       // next bss table entry
+       sub     a5, a5, a3      // arg3 = fill size in bytes
+       simcall                 // memset(a3,a4,a5)
+       bltu    a6, a7, .Lbssloop       // loop until end of bss table
+.Lnobss:
+#endif
+
+
+       /* 
+        *  Call __clibrary_init to initialize the C library:
+        *
+        *  void __clibrary_init(int argc, char ** argv, char ** environ, 
+        *              void(*init_func)(void), void(*fini_func)(void));
+        */     
+
+       // Get argv with the arguments from the ISS
+       mov     a3, sp          // tell simcall where to write argv[]
+       movi    a2, SYS_iss_set_argv
+       simcall                 // write argv[] array at a3
+
+       movi    a2, SYS_iss_argc
+       simcall                 // put argc in a2       
+
+
+//     Alternative smaller code for Xtensa TX.
+//     Many starting with simulation assume a full C env, so NOT DONE FOR NOW.
+//
+//#if XCHAL_HAVE_HALT
+//
+//     //  Assume minimalist environment for memory-constrained TX cores.
+//     //  No C library or board initialization, and no call to exit().
+//     //  However, in the interest of software regressions, for now we
+//     //  still pass parameters to main (but not the rarely used envp).
+//
+//     //mov   ARG1, a2                // argc already in a2.
+//     mov     ARG2, sp                // argv
+//     CALL    main
+//     halt
+//
+//#else /* !HALT */
+//     ...
+
+
+#if __XTENSA_CALL0_ABI__
+       mov     a12, a2                 // save argc (a2 is ARG1)
+#else
+       mov     ARG1, a2                // argc
+#endif
+       mov     ARG2, sp                // argv
+       movi    ARG3, _start_envp       // envp
+       movi    ARG4, _init             // _init
+       movi    ARG5, _fini             // _fini
+       CALL    __clibrary_init
+
+       //  Call:   int main(int argc, char ** argv, char ** environ);
+#if __XTENSA_CALL0_ABI__
+       mov     ARG1, a12               // argc
+#else
+       mov     ARG1, a2                // argc
+#endif
+       mov     ARG2, sp                // argv
+       movi    ARG3, _start_envp       // envp = [0]
+       CALL    main
+       //  The return value is the same register as the first outgoing argument.
+       CALL    exit                    // exit with main's return value
+       // Does not return here.
+
+       .size   _start, . - _start
+
+\f
+// Local Variables:
+// mode:fundamental
+// comment-start: "// "
+// comment-start-skip: "// *"
+// End: