diff options
Diffstat (limited to 'libgloss/nds32')
-rw-r--r-- | libgloss/nds32/_exit.S | 20 | ||||
-rw-r--r-- | libgloss/nds32/_getpid.S | 17 | ||||
-rw-r--r-- | libgloss/nds32/_gettimeofday.S | 10 | ||||
-rw-r--r-- | libgloss/nds32/_isatty.S | 26 | ||||
-rw-r--r-- | libgloss/nds32/_kill.S | 25 | ||||
-rw-r--r-- | libgloss/nds32/_link.S | 23 | ||||
-rw-r--r-- | libgloss/nds32/_times.S | 23 | ||||
-rw-r--r-- | libgloss/nds32/_unlink.S | 2 | ||||
-rw-r--r-- | libgloss/nds32/crt0.S | 94 | ||||
-rw-r--r-- | libgloss/nds32/crt1.S | 96 | ||||
-rw-r--r-- | libgloss/nds32/syscall_extra.h | 9 | ||||
-rw-r--r-- | libgloss/nds32/vh.h | 3 |
12 files changed, 267 insertions, 81 deletions
diff --git a/libgloss/nds32/_exit.S b/libgloss/nds32/_exit.S index 8154fbe..1a73fa2 100644 --- a/libgloss/nds32/_exit.S +++ b/libgloss/nds32/_exit.S @@ -27,22 +27,18 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef __NDS32_VH__ - #include "vh.h" -.extern _impure_ptr -TYPE3 _exit, VH_EXIT - -#else /* not __NDS32_VH__ */ - #include "../syscall.h" -#include "syscall_extra.h" - .section .text + .text .global _exit .type _exit, @function - .align 2 + .align 2 _exit: +#ifdef __NDS32_VH__ + BREAK VH_EXIT /* Generate_Exception(Breakpoint); */ +#else syscall SYS_exit /* Make syscall 'SYS_exit'. */ +#endif +.L_infinite_loop: + b .L_infinite_loop .size _exit, .-_exit - -#endif /* not __NDS32_VH__ */ diff --git a/libgloss/nds32/_getpid.S b/libgloss/nds32/_getpid.S index 086be84..c8662d2 100644 --- a/libgloss/nds32/_getpid.S +++ b/libgloss/nds32/_getpid.S @@ -28,10 +28,13 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __NDS32_VH__ - -#include "../syscall.h" -#include "syscall_extra.h" -SYS_WRAPPER _getpid, SYS_getpid - -#endif /* not __NDS32_VH__ */ + .text + .global _getpid + .type _getpid, @function + .align 2 +_getpid: + /* The getpid() function shall always be successful and + no return value is reserved to indicate an error. */ + movi $r0, 1 /* A minimal implementation, success. */ + ret + .size _getpid, .-_getpid diff --git a/libgloss/nds32/_gettimeofday.S b/libgloss/nds32/_gettimeofday.S index adc5f68..e78bd5e 100644 --- a/libgloss/nds32/_gettimeofday.S +++ b/libgloss/nds32/_gettimeofday.S @@ -30,13 +30,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __NDS32_VH__ #include "vh.h" -.extern _impure_ptr TYPE3 _gettimeofday, VH_GETTIMEOFDAY #else /* not __NDS32_VH__ */ #include "../syscall.h" #include "syscall_extra.h" -SYS_WRAPPER _gettimeofday, SYS_gettimeofday + .text + .global _gettimeofday + .type _gettimeofday, @function + .align 2 +_gettimeofday: + syscall SYS_gettimeofday + ret + .size _gettimeofday, .-_gettimeofday #endif /* not __NDS32_VH__ */ diff --git a/libgloss/nds32/_isatty.S b/libgloss/nds32/_isatty.S index c90028a..37776ed 100644 --- a/libgloss/nds32/_isatty.S +++ b/libgloss/nds32/_isatty.S @@ -27,6 +27,15 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + SYNOPSIS + #include <unistd.h> + int isatty(int fildes); + RETURN VALUE + The isatty() function shall return 1 if fildes is associated with + a terminal; otherwise, it shall return 0 and may set errno + to indicate the error. +*/ #ifdef __NDS32_VH__ #include "vh.h" @@ -37,6 +46,21 @@ TYPE0 _isatty, VH_ISATTY #include "../syscall.h" #include "syscall_extra.h" -SYS_WRAPPER _isatty, SYS_isatty + .text + .global _isatty + .type _isatty, @function + .align 2 +_isatty: + syscall SYS_isatty /* Make syscall with SWID=`SYS_isatty'. + Reture value `0' stored in $r0 means + there is something wrong. */ + bnez $r0, 1f /* Branch if success. */ + syscall SYS_geterr /* There is something wrong. */ + l.w $r15, _impure_ptr + swi $r0, [$r15] /* Set errno. */ + move $r0, #0 +1: + ret + .size _isatty, .-_isatty #endif /* not __NDS32_VH__ */ diff --git a/libgloss/nds32/_kill.S b/libgloss/nds32/_kill.S index 69d8b41..bb8c6eb 100644 --- a/libgloss/nds32/_kill.S +++ b/libgloss/nds32/_kill.S @@ -27,11 +27,20 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#ifndef __NDS32_VH__ - -#include "../syscall.h" -#include "syscall_extra.h" -SYS_WRAPPER _kill, SYS_kill - -#endif /* not __NDS32_VH__ */ +/* Upon successful completion, 0 shall be returned. Otherwise, + -1 shall be returned and errno set to indicate the error. */ + .extern _impure_ptr /* The first element is _errno. */ + .text + .global _kill + .type _kill, @function + .align 2 +_kill: + /* A minimal implementation has no concept of either signals, + nor of processes to receive those signals. So this function + should always fail with an appropriate value in errno. */ + movi $r0, #22 /* EINVAL: Invalid argument */ + l.w $r15, _impure_ptr + swi $r0, [$r15] + movi $r0, -1 /* Set return value to -1. */ + ret + .size _kill, .-_kill diff --git a/libgloss/nds32/_link.S b/libgloss/nds32/_link.S index 15016fc..7f6b7f0 100644 --- a/libgloss/nds32/_link.S +++ b/libgloss/nds32/_link.S @@ -27,10 +27,19 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __NDS32_VH__ - -#include "../syscall.h" -#include "syscall_extra.h" -SYS_WRAPPER _link, SYS_link - -#endif /* not __NDS32_VH__ */ +/* Upon successful completion, 0 shall be returned. Otherwise, + -1 shall be returned and errno set to indicate the error. */ + .extern _impure_ptr /* The first element is _errno. */ + .text + .global _link + .type _link, @function + .align 2 +_link: + /* A minimal implementation has no file system, so this function + must always fail, with an appropriate value set in errno. */ + movi $r0, #31 /* EMLINK: Too many links */ + l.w $r15, _impure_ptr + swi $r0, [$r15] + movi $r0, -1 /* Set return value to -1. */ + ret + .size _link, .-_link diff --git a/libgloss/nds32/_times.S b/libgloss/nds32/_times.S index 048de62..3343f31 100644 --- a/libgloss/nds32/_times.S +++ b/libgloss/nds32/_times.S @@ -27,10 +27,19 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __NDS32_VH__ - -#include "../syscall.h" -#include "syscall_extra.h" -SYS_WRAPPER _times, SYS_times - -#endif /* not __NDS32_VH__ */ +/* If times() fails, (clock_t)-1 shall be returned and errno set + to indicate the error. */ + .extern _impure_ptr /* The first element is _errno. */ + .text + .global _times + .type _times, @function + .align 2 +_times: + /* A minimal implementation need not offer any timing information, + so should always fail with an appropriate value in errno. */ + movi $r0, #13 /* EACCES: Permission denied */ + l.w $r15, _impure_ptr + swi $r0, [$r15] + movi $r0, -1 /* Set return value to -1. */ + ret + .size _times, .-_times diff --git a/libgloss/nds32/_unlink.S b/libgloss/nds32/_unlink.S index ec251b5..bb5989c 100644 --- a/libgloss/nds32/_unlink.S +++ b/libgloss/nds32/_unlink.S @@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "vh.h" .extern _impure_ptr -TYPE1 _lseek, VH_LSEEK +TYPE1 _unlink, VH_UNLINK #else /* not __NDS32_VH__ */ diff --git a/libgloss/nds32/crt0.S b/libgloss/nds32/crt0.S index 968b735..68a6f76 100644 --- a/libgloss/nds32/crt0.S +++ b/libgloss/nds32/crt0.S @@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ##============================================================================== +#include "syscall_extra.h" + ##------------------------------------------------------------------------------ ## Vector table setup ##------------------------------------------------------------------------------ @@ -47,6 +49,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##------------------------------------------------------------------------------ .section .text .weak _SDA_BASE_ + .weak _ITB_BASE_ + .weak _arg_init + .weak __pre_c_init + .weak __post_c_init + .weak _call_exit .global _start .type _start, @function .align 2 @@ -60,8 +67,22 @@ _start: determined by Linker. SDA stands for Small Data Access. */ la $gp, _SDA_BASE_ +#if __NDS32_EXT_EX9__ +.L_init_itb: + /* Initialization for Instruction Table Base (ITB). + The symbol _ITB_BASE_ is determined by Linker. + Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ + mfsr $r0, $MSC_CFG + srli $r0, $r0, 24 + andi $r0, $r0, 0x1 + beqz $r0, 1f /* Fall through ? */ + la $r0, _ITB_BASE_ + mtusr $r0, $ITB +1: +#endif + .L_init_sp: - /* Initialization for stack pointe. The symbol _stack is defined + /* Initialization for stack pointer. The symbol _stack is defined in linker script. Make sure $sp is 8-byte aligned. */ la $sp, _stack #if __NDS32_ISA_V3__ @@ -71,23 +92,33 @@ _start: and $sp, $sp, $r0 #endif -#if __NDS32_EX9_EXT__ -.L_init_itb: - /* Initialization for Instruction Table Base (ITB). - The symbol $_ITB_BASE_ is determined by Linker. - Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ - mfsr $r0, $MSC_CFG - srli $r0, $r0, 24 - andi $r0, $r0, 0x1 - beqz $r0, .L_zero_out_bss /* Fall through ? */ - la $r0, $_ITB_BASE_ - mtusr $r0, $ITB +#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__ +.L_init_fpu: + /* Initialize FPU + Set FUCOP_CTL.CP0EN (fucpr.b'0). */ + mfsr $r0, $FUCOP_CTL + ori $r0, $r0, 0x1 + mtsr $r0, $FUCOP_CTL + dsb + /* According to [bugzilla #9425], set flush-to-zero mode. + That is, set $FPCSR.DNZ(b'12) = 1. */ + FMFCSR $r0 + ori $r0, $r0, 0x1000 + FMTCSR $r0 + dsb #endif +.L_pre_c_init: + ! call __pre_c_init if provided + ! sample __pre_c_init is in BSP + la $r15, __pre_c_init ! load address of __pre_c_init + beqz $r15, .L_zero_out_bss ! check existence of __pre_c_init + jral $r15 ! pre-c-runtime initialization + .L_zero_out_bss: /* Zero out the bss section. Equivalence C code for follow part: - if (_end == _edata) goto .L_call_main + if (_end == _edata) goto .L_post_c_init unsinged int *ptr = _edata; while (ptr != _end) *ptr++ = 0 @@ -98,21 +129,52 @@ _start: la $r0, _edata la $r1, _end movi $r2, #0 - beq $r0, $r1, .L_call_main /* Branch if no bss. */ + beq $r0, $r1, .L_post_c_init /* Branch if no bss. */ .Lword_clear: swi.bi $r2, [$r0], #4 bne $r0, $r1, .Lword_clear -.L_call_main: +.L_post_c_init: + ! call __post_c_init if provided + ! no sample __post_c_init is provided + la $r15, __post_c_init ! load address of __post_c_init + beqz $r15, .L_arg_init ! check existence of __post_c_init + jral $r15 ! post-c-runtime initialization + +.L_arg_init: + ! argc/argv initialization if necessary + la $r7, _arg_init ! get address of _arg_init + beqz $r7, .L_clean_reg ! if there isn't _arg_init, go main + addi $sp, $sp, -512 ! allocate space for command line + ! and arguments + move $r6, $sp ! r6 = buffer addr of cmd line + move $r0, $r6 ! r0 = buffer addr of cmd line + syscall SYS_getcmdline ! get cmd line + move $r0, $r6 ! r0 = buffer addr of cmd line + addi $r1, $r6, 256 ! r1 = argv + jral $r7 ! init argc/argv + addi $r1, $r6, 256 ! r1 = argv + b .L_call_main + +.L_clean_reg: /* Prepare argc/argv/env for main function. Since there is no operating system so far, we set $r0, $r1, and $r2 to be zero. - Note: $r2 already set to zero in line 84. */ + Note: $r2 already set to zero in .L_zero_out_bss: code fragment. */ movi $r0, 0 movi $r1, 0 + movi $r2, 0 + +.L_call_main: /* Call 'main'. */ bal main + /* Call _call_exit. */ + ! call _call_exit if necessary; default implementation is in crtexit.c + la $r15, _call_exit ! load address of _call_exit + beqz $r15, .L_terminate_program ! no _call_exit? go exit + jral $r15 ! _call_exit will never return + .L_terminate_program: /* There are two ways to terminate program: 1. User "syscall 0x1" directly. diff --git a/libgloss/nds32/crt1.S b/libgloss/nds32/crt1.S index 2ff2eea..ec8b866 100644 --- a/libgloss/nds32/crt1.S +++ b/libgloss/nds32/crt1.S @@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## ##============================================================================== +#include "syscall_extra.h" + ##------------------------------------------------------------------------------ ## Vector table setup ##------------------------------------------------------------------------------ @@ -47,6 +49,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ##------------------------------------------------------------------------------ .section .text .weak _SDA_BASE_ + .weak _ITB_BASE_ + .weak _arg_init + .weak __pre_c_init + .weak __post_c_init + .weak _call_exit .global _start .type _start, @function .align 2 @@ -60,8 +67,22 @@ _start: determined by Linker. SDA stands for Small Data Access. */ la $gp, _SDA_BASE_ +#if __NDS32_EXT_EX9__ +.L_init_itb: + /* Initialization for Instruction Table Base (ITB). + The symbol _ITB_BASE_ is determined by Linker. + Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ + mfsr $r0, $MSC_CFG + srli $r0, $r0, 24 + andi $r0, $r0, 0x1 + beqz $r0, 1f /* Fall through ? */ + la $r0, _ITB_BASE_ + mtusr $r0, $ITB +1: +#endif + .L_init_sp: - /* Initialization for stack pointe. The symbol _stack is defined + /* Initialization for stack pointer. The symbol _stack is defined in linker script. Make sure $sp is 8-byte aligned. */ la $sp, _stack #if __NDS32_ISA_V3__ @@ -71,19 +92,29 @@ _start: and $sp, $sp, $r0 #endif -#if __NDS32_EX9_EXT__ -.L_init_itb: - /* Initialization for Instruction Table Base (ITB). - The symbol $_ITB_BASE_ is determined by Linker. - Set $ITB only if MSC_CFG.EIT (cr4.b'24) is set. */ - mfsr $r0, $MSC_CFG - srli $r0, $r0, 24 - andi $r0, $r0, 0x1 - beqz $r0, .L_zero_out_bss /* Fall through ? */ - la $r0, $_ITB_BASE_ - mtusr $r0, $ITB +#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__ +.L_init_fpu: + /* Initialize FPU + Set FUCOP_CTL.CP0EN (fucpr.b'0). */ + mfsr $r0, $FUCOP_CTL + ori $r0, $r0, 0x1 + mtsr $r0, $FUCOP_CTL + dsb + /* According to [bugzilla #9425], set flush-to-zero mode. + That is, set $FPCSR.DNZ(b'12) = 1. */ + FMFCSR $r0 + ori $r0, $r0, 0x1000 + FMTCSR $r0 + dsb #endif +.L_pre_c_init: + ! call __pre_c_init if provided + ! sample __pre_c_init is in BSP + la $r15, __pre_c_init ! load address of __pre_c_init + beqz $r15, .L_zero_out_bss ! check existence of __pre_c_init + jral $r15 ! pre-c-runtime initialization + .L_zero_out_bss: /* Zero out the bss section. Equivalence C code for follow part: @@ -97,28 +128,61 @@ _start: */ la $r0, _edata la $r1, _end - beq $r0, $r1, .L_call_main /* Branch if no bss. */ movi $r2, #0 + beq $r0, $r1, .L_cpp_init /* Branch if no bss. */ .Lword_clear: swi.bi $r2, [$r0], #4 bne $r0, $r1, .Lword_clear -.L_call_main: +.L_cpp_init: /* Call '_init' to invoke constructors. */ jal _init /* Register '_fini' into atexit() to invoke destructors when exit() has been reached. */ la $r0, _fini jal atexit + +.L_post_c_init: + ! call __post_c_init if provided + ! no sample __post_c_init is provided + la $r15, __post_c_init ! load address of __post_c_init + beqz $r15, .L_arg_init ! check existence of __post_c_init + jral $r15 ! post-c-runtime initialization + +.L_arg_init: + ! argc/argv initialization if necessary + la $r7, _arg_init ! get address of _arg_init + beqz $r7, .L_clean_reg ! if there isn't _arg_init, go main + addi $sp, $sp, -512 ! allocate space for command line + ! and arguments + move $r6, $sp ! r6 = buffer addr of cmd line + move $r0, $r6 ! r0 = buffer addr of cmd line + syscall SYS_getcmdline ! get cmd line + move $r0, $r6 ! r0 = buffer addr of cmd line + addi $r1, $r6, 256 ! r1 = argv + jral $r7 ! init argc/argv + addi $r1, $r6, 256 ! r1 = argv + b .L_call_main + +.L_clean_reg: /* Prepare argc/argv/env for main function. Since there is no operating system so far, - we set $r0, $r1, and $r2 to be zero. */ + we set $r0, $r1, and $r2 to be zero. + Note: $r2 already set to zero in .L_zero_out_bss: code fragment. */ movi $r0, 0 movi $r1, 0 movi $r2, 0 + +.L_call_main: /* Call 'main'. */ bal main + /* Call _call_exit. */ + ! call _call_exit if necessary; default implementation is in crtexit.c + la $r15, _call_exit ! load address of _call_exit + beqz $r15, .L_terminate_program ! no _call_exit? go exit + jral $r15 ! _call_exit will never return + .L_terminate_program: /* There are two ways to terminate program: 1. User "syscall 0x1" directly. @@ -128,7 +192,7 @@ _start: Currently, we use option 2 as a solution to follow C99 5.1.2.2.3, but aware that general exit() will do some cleanup procedures which may result in large-memory-footprints. */ - + bal exit .L_forever_loop: diff --git a/libgloss/nds32/syscall_extra.h b/libgloss/nds32/syscall_extra.h index 7af4a45..7c69489 100644 --- a/libgloss/nds32/syscall_extra.h +++ b/libgloss/nds32/syscall_extra.h @@ -32,11 +32,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* These are additional syscalls for nds32 target. */ -#define SYS_rename 3001 -#define SYS_isatty 3002 -#define SYS_system 3003 +#define SYS_rename 3001 +#define SYS_isatty 3002 +#define SYS_system 3003 -#define SYS_geterr 6001 +#define SYS_geterr 6001 +#define SYS_getcmdline 6002 /* Define macros that generate assembly output. */ diff --git a/libgloss/nds32/vh.h b/libgloss/nds32/vh.h index 4ee3e89..ca3a43f 100644 --- a/libgloss/nds32/vh.h +++ b/libgloss/nds32/vh.h @@ -43,6 +43,9 @@ BREAK #SWID definition: #define VH_ISATTY 0x7F2B #define VH_SYSTEM 0x7F2C #define VH_GETERR 0x7F2D /* The method we get errno. */ +#define VH_GETPID 0x7F2E +#define VH_KILL 0x7F2F +#define VH_TIMES 0x7F30 /* Define macros that generate assembly output. |