xtensa: merge crt1-*.S
We had two assembly files to prepare for entry into C domain, one intended for the simulator and one intended for real boards. - Both files merged into a single crt1.S for either simulated or real targets - Extra logic to populate command line arguments from simulator removed, we don't use it. - BSS zeroing logic from crt1-boards.S used - Reference to missing reset-unneeded.S removed - exit() implementation moved to fatal.c, now invokes a kernel panic if we are not running under the simulator Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
b7aa6b7bd0
commit
51df312abc
4 changed files with 31 additions and 343 deletions
|
@ -8,11 +8,9 @@ else
|
||||||
# Use our own routines implmented in assembly
|
# Use our own routines implmented in assembly
|
||||||
obj-atomic=atomic.o
|
obj-atomic=atomic.o
|
||||||
endif
|
endif
|
||||||
obj-y = ${obj-atomic} cpu_idle.o fatal.o \
|
obj-y = ${obj-atomic} cpu_idle.o fatal.o crt1.o \
|
||||||
swap.o thread.o xt_zephyr.o xtensa_context.o xtensa_intr_asm.o \
|
swap.o thread.o xt_zephyr.o xtensa_context.o xtensa_intr_asm.o \
|
||||||
xtensa_intr.o xtensa_vectors.o irq_manage.o
|
xtensa_intr.o xtensa_vectors.o irq_manage.o
|
||||||
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||||
obj-$(CONFIG_SIMULATOR_XTENSA) += crt1-sim.o
|
|
||||||
obj-$(CONFIG_BOARD_XTENSA) += crt1-boards.o
|
|
||||||
# Keep this last so that vague linking works
|
# Keep this last so that vague linking works
|
||||||
obj-y += sw_isr_table.o
|
obj-y += sw_isr_table.o
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtensa/simboard.h>
|
|
||||||
#include <xtensa/simcall.h>
|
|
||||||
#include <xtensa/coreasm.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* Exports */
|
|
||||||
.global _start
|
|
||||||
.global __start
|
|
||||||
.global exit
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Imports
|
|
||||||
* main from user application
|
|
||||||
* __stack from linker script (see LSP Ref Manual)
|
|
||||||
*/
|
|
||||||
|
|
||||||
.type _Cstart, @function
|
|
||||||
.type exit, @function
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros to abstract away ABI differences */
|
|
||||||
|
|
||||||
#if __XTENSA_CALL0_ABI__
|
|
||||||
# define ENTRY
|
|
||||||
# define CALL call0
|
|
||||||
# define CALLX callx0
|
|
||||||
# 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 ENTRY entry sp, 0x20
|
|
||||||
# define CALL call4
|
|
||||||
# define CALLX callx4
|
|
||||||
# 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:
|
|
||||||
/*
|
|
||||||
* _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__
|
|
||||||
/* PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
|
|
||||||
movi a3, PS_UM
|
|
||||||
# else
|
|
||||||
/* PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
|
|
||||||
movi a3, PS_UM|PS_WOE
|
|
||||||
# endif
|
|
||||||
wsr a3, PS
|
|
||||||
rsync
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do any initialization that affects the memory map, such as
|
|
||||||
* setting up TLB entries, that needs to be done before we can
|
|
||||||
* successfully clear BSS (e.g. if some BSS segments are in
|
|
||||||
* remapped areas).
|
|
||||||
*
|
|
||||||
* NOTE: This hook works where the reset vector does not unpack
|
|
||||||
* segments (see "ROM packing" in the LSP manual), or where
|
|
||||||
* unpacking of segments is not affected by memory remapping.
|
|
||||||
* If ROM unpacking is affected, TLB setup must be done in
|
|
||||||
* assembler from the reset vector.
|
|
||||||
*
|
|
||||||
* The __memmap_init() routine can be a C function, however it
|
|
||||||
* does not have BSS initialized! In particular, __memmap_init()
|
|
||||||
* cannot set BSS variables, i.e. uninitialized global variables
|
|
||||||
* (they'll be wiped out by the following BSS clear), nor can it
|
|
||||||
* assume they are yet initialized to zero.
|
|
||||||
*
|
|
||||||
* The __memmap_init() function is optional. It is marked as a
|
|
||||||
* weak symbol, so that it gets valued zero if not defined.
|
|
||||||
*/
|
|
||||||
.weak __memmap_init
|
|
||||||
movi a4, __memmap_init
|
|
||||||
beqz a4, 1f
|
|
||||||
CALLX a4
|
|
||||||
1:
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Call: int _Cstart(); */
|
|
||||||
CALL _Cstart
|
|
||||||
/* The return value is the same register as the first outgoing
|
|
||||||
* argument.
|
|
||||||
*/
|
|
||||||
CALL exit
|
|
||||||
/* Does not return here. */
|
|
||||||
|
|
||||||
.size _start, . - _start
|
|
||||||
|
|
||||||
.align 4
|
|
||||||
exit:
|
|
||||||
ENTRY
|
|
||||||
mov a3, a2
|
|
||||||
movi a2, SYS_exit
|
|
||||||
simcall
|
|
||||||
|
|
||||||
.size exit, . - exit
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Local Variables:
|
|
||||||
* mode:fundamental
|
|
||||||
* comment-start: "/* "
|
|
||||||
* comment-start-skip: "/* *"
|
|
||||||
* End:
|
|
||||||
*/
|
|
|
@ -4,33 +4,26 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For most hardware / boards, this code sets up the C calling context
|
|
||||||
* (setting up stack, PS, and clearing BSS) and jumps to __clibrary_start
|
|
||||||
* which sets up the C library, calls constructors and registers destructors,
|
|
||||||
* and calls main().
|
|
||||||
*
|
|
||||||
* Control arrives here at _start from the reset vector or from crt0-app.S.
|
* Control arrives here at _start from the reset vector or from crt0-app.S.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtensa/coreasm.h>
|
#include <xtensa_rtos.h>
|
||||||
#include "xtos-internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Exports */
|
/* Exports */
|
||||||
.global _start
|
.global _start
|
||||||
.global exit
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Imports
|
* Imports
|
||||||
* main from user application
|
|
||||||
* board_init board-specific (uart/mingloss/tinygloss.c)
|
|
||||||
* xthal_dcache_all_writeback from HAL library
|
|
||||||
* __stack from linker script (see LSP Ref Manual)
|
* __stack from linker script (see LSP Ref Manual)
|
||||||
* _bss_table_start from linker script (see LSP Ref Manual)
|
* _bss_table_start from linker script (see LSP Ref Manual)
|
||||||
* _bss_table_end from linker script (see LSP Ref Manual)
|
* _bss_table_end from linker script (see LSP Ref Manual)
|
||||||
|
* _Cstart Entry point into Zephyr C domain
|
||||||
|
* __stack from linker script (see LSP Ref Manual)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.type main, @function
|
.global __start
|
||||||
|
.type _Cstart, @function
|
||||||
|
|
||||||
|
|
||||||
/* Macros to abstract away ABI differences */
|
/* Macros to abstract away ABI differences */
|
||||||
|
|
||||||
|
@ -52,14 +45,13 @@
|
||||||
# define ARG5 a10 /* 5th outgoing call argument */
|
# define ARG5 a10 /* 5th outgoing call argument */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
|
__start:
|
||||||
/*
|
/*
|
||||||
* _start is typically NOT at the beginning of the text segment --
|
* _start is typically NOT at the beginning of the text segment --
|
||||||
* it is always called from either the reset vector or other code
|
* it is always called from either the reset vector or other code
|
||||||
* that does equivalent initialization (such as crt0-app.S).
|
* that does equivalent initialization (such as crt0-app.S).
|
||||||
*
|
*
|
||||||
|
@ -77,17 +69,13 @@ _start:
|
||||||
* Keep a0 zero. It is used to initialize a few things.
|
* Keep a0 zero. It is used to initialize a few things.
|
||||||
* It is also the return address, where zero indicates
|
* It is also the return address, where zero indicates
|
||||||
* that the frame used by _start is the bottommost frame.
|
* that the frame used by _start is the bottommost frame.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* not needed for Xtensa TX */
|
/* not needed for Xtensa TX */
|
||||||
#if !XCHAL_HAVE_HALT || !XCHAL_HAVE_BOOTLOADER
|
#if !XCHAL_HAVE_HALT || !XCHAL_HAVE_BOOTLOADER
|
||||||
movi a0, 0 /* keep this register zero. */
|
movi a0, 0 /* keep this register zero. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XTOS_RESET_UNNEEDED && !XCHAL_HAVE_HALT
|
|
||||||
#include "reset-unneeded.S"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the stack pointer.
|
* Initialize the stack pointer.
|
||||||
* See the "ABI and Software Conventions" chapter in the
|
* See the "ABI and Software Conventions" chapter in the
|
||||||
|
@ -95,7 +83,7 @@ _start:
|
||||||
*
|
*
|
||||||
* NOTE: Because the _start routine does not use any memory in its
|
* NOTE: Because the _start routine does not use any memory in its
|
||||||
* stack frame, and because all of its CALL instructions use a
|
* stack frame, and because all of its CALL instructions use a
|
||||||
* window size of 4 (or zero), the stack frame for _start can be empty.
|
* window size of 4, the stack frame for _start can be empty.
|
||||||
*/
|
*/
|
||||||
movi sp, __stack
|
movi sp, __stack
|
||||||
|
|
||||||
|
@ -144,7 +132,6 @@ _start:
|
||||||
CALLX a4
|
CALLX a4
|
||||||
1:
|
1:
|
||||||
|
|
||||||
|
|
||||||
#if !XCHAL_HAVE_BOOTLOADER /* boot loader takes care of zeroing BSS */
|
#if !XCHAL_HAVE_BOOTLOADER /* boot loader takes care of zeroing BSS */
|
||||||
|
|
||||||
# ifdef __XTENSA_CALL0_ABI__
|
# ifdef __XTENSA_CALL0_ABI__
|
||||||
|
@ -189,75 +176,11 @@ _start:
|
||||||
|
|
||||||
bltu a6, a7, .L0zte /* loop until end of table of *.bss sections */
|
bltu a6, a7, .L0zte /* loop until end of table of *.bss sections */
|
||||||
.L3zte:
|
.L3zte:
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif /* !XCHAL_HAVE_BOOTLOADER */
|
||||||
|
|
||||||
/*
|
/* Enter C domain, never returns from here */
|
||||||
* We can now call C code, the C calling environment has been
|
CALL _Cstart
|
||||||
* initialized.
|
|
||||||
*
|
|
||||||
* From this point on, we use ABI-specific macros to refer to
|
|
||||||
* registers a0 .. a15 (ARG#).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if XCHAL_HAVE_HALT
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Assume minimalist environment for memory-constrained TX cores.
|
|
||||||
* No C library or board initialization, no parameters passed to main
|
|
||||||
* (assume declared as "void main(void)") and no call to exit().
|
|
||||||
*/
|
|
||||||
CALL main
|
|
||||||
halt
|
|
||||||
|
|
||||||
#else /* !HALT */
|
|
||||||
|
|
||||||
.type board_init, @function
|
|
||||||
.type exit, @function
|
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the board (eg. UART, etc). */
|
|
||||||
CALL board_init
|
|
||||||
|
|
||||||
/* Call: int main(int argc, char ** argv, char ** environ); */
|
|
||||||
movi ARG1, _start_argc /* argc address */
|
|
||||||
movi ARG2, _start_argv /* argv = ["", 0] */
|
|
||||||
movi ARG3, _start_envp /* envp = [0] */
|
|
||||||
l32i ARG1, ARG1, 0 /* argc = 1 */
|
|
||||||
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. */
|
|
||||||
|
|
||||||
.data
|
|
||||||
/*
|
|
||||||
* Mark argc/argv/envp parameters as weak so that an external
|
|
||||||
* object file can override them.
|
|
||||||
*/
|
|
||||||
.weak _start_argc, _start_argv, _start_envp
|
|
||||||
.align 4
|
|
||||||
_start_argv:
|
|
||||||
.word _start_null /* empty program name */
|
|
||||||
_start_null:
|
|
||||||
_start_envp:
|
|
||||||
/* end of argv array, empty string, empty environ */
|
|
||||||
.word 0
|
|
||||||
_start_argc:
|
|
||||||
.word 1 /* one argument (program name) */
|
|
||||||
.text
|
|
||||||
|
|
||||||
#endif /* !HALT */
|
|
||||||
|
|
||||||
.size _start, . - _start
|
.size _start, . - _start
|
||||||
|
|
||||||
.align 4
|
|
||||||
exit:
|
|
||||||
#if XCHAL_HAVE_INTERRUPTS
|
|
||||||
waiti 15
|
|
||||||
#endif
|
|
||||||
j exit
|
|
||||||
|
|
||||||
.size exit, . - exit
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
||||||
_SysFatalErrorHandler(reason, pEsf);
|
_SysFatalErrorHandler(reason, pEsf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_PRINTK
|
#ifdef CONFIG_PRINTK
|
||||||
static char *cause_str(unsigned int cause_code)
|
static char *cause_str(unsigned int cause_code)
|
||||||
{
|
{
|
||||||
|
@ -198,8 +199,21 @@ FUNC_NORETURN void ReservedInterruptHandler(unsigned int intNo)
|
||||||
_NanoFatalErrorHandler(_NANO_ERR_RESERVED_IRQ, &_default_esf);
|
_NanoFatalErrorHandler(_NANO_ERR_RESERVED_IRQ, &_default_esf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implemented in Xtensa HAL */
|
void exit(int return_code)
|
||||||
extern FUNC_NORETURN void exit(int exit_code);
|
{
|
||||||
|
#ifdef XT_SIMULATOR
|
||||||
|
__asm__ (
|
||||||
|
"mov a3, %[code]\n\t"
|
||||||
|
"movi a2, %[call]\n\t"
|
||||||
|
"simcall\n\t"
|
||||||
|
:
|
||||||
|
: [code] "r" (return_code), [call] "I" (SYS_exit)
|
||||||
|
: "a3", "a2");
|
||||||
|
#else
|
||||||
|
printk("exit(%d)\n", return_code);
|
||||||
|
k_panic();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue