diff --git a/arch/xtensa/core/Makefile b/arch/xtensa/core/Makefile index 5eec07099d8..fdbbf5522a5 100644 --- a/arch/xtensa/core/Makefile +++ b/arch/xtensa/core/Makefile @@ -8,11 +8,9 @@ else # Use our own routines implmented in assembly obj-atomic=atomic.o 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 \ xtensa_intr.o xtensa_vectors.o irq_manage.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 obj-y += sw_isr_table.o diff --git a/arch/xtensa/core/crt1-sim.S b/arch/xtensa/core/crt1-sim.S deleted file mode 100644 index 22af3708f07..00000000000 --- a/arch/xtensa/core/crt1-sim.S +++ /dev/null @@ -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 -#include -#include - - -/* 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: - */ diff --git a/arch/xtensa/core/crt1-boards.S b/arch/xtensa/core/crt1.S similarity index 69% rename from arch/xtensa/core/crt1-boards.S rename to arch/xtensa/core/crt1.S index c24092c80b0..8aeb3962806 100644 --- a/arch/xtensa/core/crt1-boards.S +++ b/arch/xtensa/core/crt1.S @@ -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. */ -#include -#include "xtos-internal.h" - +#include /* Exports */ .global _start -.global exit /* * 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) * _bss_table_start 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 */ @@ -52,14 +45,13 @@ # define ARG5 a10 /* 5th outgoing call argument */ #endif - -/**************************************************************************/ - .text .align 4 + _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 * 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. * It is also the return address, where zero indicates * that the frame used by _start is the bottommost frame. + * */ - /* not needed for Xtensa TX */ #if !XCHAL_HAVE_HALT || !XCHAL_HAVE_BOOTLOADER movi a0, 0 /* keep this register zero. */ #endif -#if XTOS_RESET_UNNEEDED && !XCHAL_HAVE_HALT -#include "reset-unneeded.S" -#endif - /* * Initialize the stack pointer. * 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 * 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 @@ -144,7 +132,6 @@ _start: CALLX a4 1: - #if !XCHAL_HAVE_BOOTLOADER /* boot loader takes care of zeroing BSS */ # ifdef __XTENSA_CALL0_ABI__ @@ -189,75 +176,11 @@ _start: bltu a6, a7, .L0zte /* loop until end of table of *.bss sections */ .L3zte: -#endif +#endif /* !XCHAL_HAVE_BOOTLOADER */ - /* - * We can now call C code, the C calling environment has been - * 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 */ + /* Enter C domain, never returns from here */ + CALL _Cstart .size _start, . - _start - .align 4 -exit: -#if XCHAL_HAVE_INTERRUPTS - waiti 15 -#endif - j exit - - .size exit, . - exit - diff --git a/arch/xtensa/core/fatal.c b/arch/xtensa/core/fatal.c index 98fb3f4eef5..6a31b98a9c9 100644 --- a/arch/xtensa/core/fatal.c +++ b/arch/xtensa/core/fatal.c @@ -91,6 +91,7 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason, _SysFatalErrorHandler(reason, pEsf); } + #ifdef CONFIG_PRINTK 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); } -/* Implemented in Xtensa HAL */ -extern FUNC_NORETURN void exit(int exit_code); +void exit(int return_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 +} /** *