diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-03-23 21:36:10 +0300 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 2006-03-23 21:36:10 +0300 |
commit | 5ca8637aa72d6794bc6b5164b827333f6b97b593 (patch) | |
tree | db8e90b61f86657ae268bab1255270f5d324673e /newlib | |
parent | f84325d0899e5052fd59892ece265f7c2bd6c6a7 (diff) |
2006-03-23 Mark Mitchell <mark@codesourcery.com>
* libc/sys/arm/Makefile.am (extra_objs): Add _exit.o _nmi_isr.o
_fault_isr.o.
* libc/sys/arm/Makefile.in: Regenerated.
* libc/sys/arm/_exit.c: New file.
* libc/sys/arm/_fault_isr.c: Likewise.
* libc/sys/arm/_nmi_isr.c: Likewise.
* libc/sys/arm/configure.in (--enable-newlib-arm-v7m): New option.
* libc/sys/arm/configure:
* libc/sys/arm/crt0.S (_start): Do not use semihosting calls in
_start when configured for ARM V7M. Do not call
initialise_monitor_handles. Indent preprocessor directives.
(.isr_vector): New section, on ARM V7M.
* libc/sys/arm/swi.h (do_AngelSWI): New function.
* syscalls.c (_exit): Remove.
(do_AngelSWI): Likewise.
(CHECK_INIT): Remove.
(remap_handle): Call initialise_monitor_handles.
(__arm_monitor_handles_lock): New variable.
(initialise_monitor_handles): Make sure to run only once.
Diffstat (limited to 'newlib')
-rw-r--r-- | newlib/libc/sys/arm/Makefile.am | 2 | ||||
-rw-r--r-- | newlib/libc/sys/arm/Makefile.in | 2 | ||||
-rw-r--r-- | newlib/libc/sys/arm/_exit.c | 18 | ||||
-rw-r--r-- | newlib/libc/sys/arm/_fault_isr.c | 16 | ||||
-rw-r--r-- | newlib/libc/sys/arm/_nmi_isr.c | 16 | ||||
-rwxr-xr-x | newlib/libc/sys/arm/configure | 119 | ||||
-rw-r--r-- | newlib/libc/sys/arm/configure.in | 16 | ||||
-rw-r--r-- | newlib/libc/sys/arm/crt0.S | 109 | ||||
-rw-r--r-- | newlib/libc/sys/arm/swi.h | 21 | ||||
-rw-r--r-- | newlib/libc/sys/arm/syscalls.c | 70 |
10 files changed, 255 insertions, 134 deletions
diff --git a/newlib/libc/sys/arm/Makefile.am b/newlib/libc/sys/arm/Makefile.am index 7749d4aff..96da666c7 100644 --- a/newlib/libc/sys/arm/Makefile.am +++ b/newlib/libc/sys/arm/Makefile.am @@ -7,7 +7,7 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) noinst_LIBRARIES = lib.a if MAY_SUPPLY_SYSCALLS -extra_objs = libcfunc.o trap.o syscalls.o +extra_objs = libcfunc.o trap.o syscalls.o _exit.o _nmi_isr.o _fault_isr.o else extra_objs = endif diff --git a/newlib/libc/sys/arm/Makefile.in b/newlib/libc/sys/arm/Makefile.in index 323db9c9b..bbe3f0dab 100644 --- a/newlib/libc/sys/arm/Makefile.in +++ b/newlib/libc/sys/arm/Makefile.in @@ -88,7 +88,7 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) noinst_LIBRARIES = lib.a -@MAY_SUPPLY_SYSCALLS_TRUE@extra_objs = libcfunc.o trap.o syscalls.o +@MAY_SUPPLY_SYSCALLS_TRUE@extra_objs = @MAY_SUPPLY_SYSCALLS_TRUE@libcfunc.o trap.o syscalls.o _exit.o _nmi_isr.o _fault_isr.o @MAY_SUPPLY_SYSCALLS_FALSE@extra_objs = lib_a_SOURCES = aeabi_atexit.c diff --git a/newlib/libc/sys/arm/_exit.c b/newlib/libc/sys/arm/_exit.c new file mode 100644 index 000000000..409cccc32 --- /dev/null +++ b/newlib/libc/sys/arm/_exit.c @@ -0,0 +1,18 @@ +#include <_ansi.h> +#include "swi.h" + +void _exit _PARAMS ((int)); + +void +_exit (int n) +{ + /* FIXME: return code is thrown away. */ + +#ifdef ARM_RDI_MONITOR + do_AngelSWI (AngelSWI_Reason_ReportException, + (void *) ADP_Stopped_ApplicationExit); +#else + asm ("swi %a0" :: "i" (SWI_Exit)); +#endif + n = n; +} diff --git a/newlib/libc/sys/arm/_fault_isr.c b/newlib/libc/sys/arm/_fault_isr.c new file mode 100644 index 000000000..1272eb56a --- /dev/null +++ b/newlib/libc/sys/arm/_fault_isr.c @@ -0,0 +1,16 @@ +#include "newlib.h" + +#ifdef _ARM_V7M + +/* Called when a hardware fault occurs. Users can replace this + function. */ + +void +_fault_isr() +{ + /* Sit an endless loop so that the user can analyze the situation + from the debugger. */ + while (1); +} + +#endif diff --git a/newlib/libc/sys/arm/_nmi_isr.c b/newlib/libc/sys/arm/_nmi_isr.c new file mode 100644 index 000000000..81b60ea13 --- /dev/null +++ b/newlib/libc/sys/arm/_nmi_isr.c @@ -0,0 +1,16 @@ +#include "newlib.h" + +#ifdef _ARM_V7M + +/* Called when a non-maskable interrupt occurs. Users can replace this + function. */ + +void +_nmi_isr() +{ + /* Sit an endless loop so that the user can analyze the situation + from the debugger. */ + while (1); +} + +#endif diff --git a/newlib/libc/sys/arm/configure b/newlib/libc/sys/arm/configure index 1f40c98f3..716b5d42c 100755 --- a/newlib/libc/sys/arm/configure +++ b/newlib/libc/sys/arm/configure @@ -12,6 +12,9 @@ ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help +AS_HELP_STRING(--enable-newlib-arm-v7m, + Assume code will run on ARM V7M.)" +ac_help="$ac_help --enable-multilib build many library versions (default)" ac_help="$ac_help --enable-target-optspace optimize for space" @@ -561,6 +564,25 @@ ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. +# Check whether --enable-newlib-arm-v7m or --disable-newlib-arm-v7m was given. +if test "${enable_newlib_arm_v7m+set}" = set; then + enableval="$enable_newlib_arm_v7m" + case "$enableval" in + yes) armv7m=yes ;; + no) armv7m=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-arm-v7m" 1>&2; exit 1; } ;; + esac +else + armv7m=no +fi + +if test "${armv7m}" = "yes"; then + cat >> confdefs.h <<\EOF +#define _ARM_V7M 1 +EOF + +fi + am__api_version="1.4" # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -574,7 +596,7 @@ am__api_version="1.4" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:578: checking for a BSD compatible install" >&5 +echo "configure:600: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -627,7 +649,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:631: checking whether build environment is sane" >&5 +echo "configure:653: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -684,7 +706,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:688: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:710: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -717,12 +739,12 @@ else fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:721: checking for Cygwin environment" >&5 +echo "configure:743: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 726 "configure" +#line 748 "configure" #include "confdefs.h" int main() { @@ -733,7 +755,7 @@ int main() { return __CYGWIN__; ; return 0; } EOF -if { (eval echo configure:737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -750,19 +772,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:754: checking for mingw32 environment" >&5 +echo "configure:776: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 759 "configure" +#line 781 "configure" #include "confdefs.h" int main() { return __MINGW32__; ; return 0; } EOF -if { (eval echo configure:766: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -932,7 +954,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:936: checking host system type" >&5 +echo "configure:958: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -953,7 +975,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:957: checking target system type" >&5 +echo "configure:979: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -971,7 +993,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:975: checking build system type" >&5 +echo "configure:997: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1014,7 +1036,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6 -echo "configure:1018: checking for working aclocal-${am__api_version}" >&5 +echo "configure:1040: checking for working aclocal-${am__api_version}" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1027,7 +1049,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:1031: checking for working autoconf" >&5 +echo "configure:1053: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1040,7 +1062,7 @@ else fi echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6 -echo "configure:1044: checking for working automake-${am__api_version}" >&5 +echo "configure:1066: checking for working automake-${am__api_version}" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1053,7 +1075,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:1057: checking for working autoheader" >&5 +echo "configure:1079: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1066,7 +1088,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:1070: checking for working makeinfo" >&5 +echo "configure:1092: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -1091,7 +1113,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1095: checking for $ac_word" >&5 +echo "configure:1117: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1121,7 +1143,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1125: checking for $ac_word" >&5 +echo "configure:1147: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1170,7 +1192,7 @@ fi fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1174: checking whether we are using GNU C" >&5 +echo "configure:1196: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1179,7 +1201,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1194,7 +1216,7 @@ if test $ac_cv_prog_gcc = yes; then ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1198: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1220: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1225,7 +1247,7 @@ fi # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1229: checking for $ac_word" >&5 +echo "configure:1251: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1257,7 +1279,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1261: checking for $ac_word" >&5 +echo "configure:1283: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1289,7 +1311,7 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1293: checking for $ac_word" >&5 +echo "configure:1315: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1321,7 +1343,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1325: checking for $ac_word" >&5 +echo "configure:1347: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1366,7 +1388,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1370: checking for a BSD compatible install" >&5 +echo "configure:1392: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1423,7 +1445,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_given_INSTALL=$INSTALL echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:1427: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:1449: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" @@ -1457,7 +1479,7 @@ if false; then echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:1461: checking for executable suffix" >&5 +echo "configure:1483: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1467,7 +1489,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:1471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:1493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj) ;; @@ -1634,15 +1656,34 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed # Without the "./", some shells look in PATH for config.status. diff --git a/newlib/libc/sys/arm/configure.in b/newlib/libc/sys/arm/configure.in index eeac4889f..21e7ea6c9 100644 --- a/newlib/libc/sys/arm/configure.in +++ b/newlib/libc/sys/arm/configure.in @@ -7,6 +7,22 @@ AC_INIT(trap.S) dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. AC_CONFIG_AUX_DIR(../../../..) +dnl If requested, generate code designed to run directly on ARM V7M +dnl hardware. As a result, startup code will not rely on simulator +dnl support. +AC_ARG_ENABLE(newlib-arm-v7m, + AS_HELP_STRING([--enable-newlib-arm-v7m], + [Assume code will run on ARM V7M.]), + [case "$enableval" in + yes) armv7m=yes ;; + no) armv7m=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-arm-v7m) ;; + esac], + [armv7m=no]) +if test "${armv7m}" = "yes"; then + AC_DEFINE(_ARM_V7M, 1) +fi + NEWLIB_CONFIGURE(../../..) AC_OUTPUT(Makefile) diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S index c750ca819..d84983ec8 100644 --- a/newlib/libc/sys/arm/crt0.S +++ b/newlib/libc/sys/arm/crt0.S @@ -43,31 +43,34 @@ .fnstart #endif -/* Start by setting up a stack */ -#ifdef ARM_RDP_MONITOR + /* Start by setting up a stack */ +#ifdef _ARM_V7M + /* On ARM V7M, the stack pointer is set up at CPU reset. */ +#else +# ifdef ARM_RDP_MONITOR /* Issue Demon SWI to read stack info */ swi SWI_GetEnv /* Returns command line in r0 */ mov sp,r1 /* and the highest memory address in r1 */ ldr sl, .LC2 /* stack limit is at end of data */ add sl, sl, #256 /* allow slop for stack overflow handling */ /* and small frames */ -#else -#ifdef ARM_RDI_MONITOR +# else +# ifdef ARM_RDI_MONITOR /* Issue Angel SWI to read stack info */ mov r0, #AngelSWI_Reason_HeapInfo adr r1, .LC0 /* point at ptr to 4 words to receive data */ -#if defined(__thumb2__) +# if defined(__thumb2__) bkpt AngelSWI -#else +# else /* We are always in ARM mode for startup */ AngelSWIAsm AngelSWI_ARM -#endif +# endif ldr r0, .LC0 /* point at values read */ ldr sp, [r0, #8] ldr sl, [r0, #12] add sl, sl, #256 /* allow slop for stack overflow handling */ /* and small frames */ -#else +# else /* Set up the stack pointer to a fixed value */ ldr r3, .LC0 mov sp, r3 @@ -79,8 +82,10 @@ However, it ensures that this simple crt0 world will not immediately cause an overflow event: */ sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */ +# endif +# endif #endif -#endif + /* Zero the memory in the .bss section. */ mov a2, #0 /* Second arg: fill value */ mov fp, a2 /* Null frame pointer */ @@ -103,38 +108,39 @@ __change_mode: #endif bl FUNCTION (memset) -#if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR) + /* For ARM V7M, we do not want to have semihosting traps in + crt0.o, so that people can use the same programs both with + and without semihosting. */ +#if ((!defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)) \ + || defined (_ARM_V7M)) mov r0, #0 /* no arguments */ mov r1, #0 /* no argv either */ #else - /* Need to set up standard file handles */ - bl FUNCTION (initialise_monitor_handles) - -#ifdef ARM_RDP_MONITOR +# ifdef ARM_RDP_MONITOR swi SWI_GetEnv /* sets r0 to point to the command line */ mov r1, r0 -#else +# else mov r0, #AngelSWI_Reason_GetCmdLine adr r1, .LC30 /* Space for command line */ AngelSWIAsm AngelSWI ldr r1, .LC30 -#endif +# endif /* Parse string at r1 */ mov r0, #0 /* count of arguments so far */ /* Push a NULL argument onto the end of the list. */ -#ifdef __thumb__ +# ifdef __thumb__ push {r0} -#else +# else stmfd sp!, {r0} -#endif +# endif .LC10: /* Skip leading blanks */ -#ifdef __thumb__ +# ifdef __thumb__ ldrb r3, [r1] add r1, #1 -#else +# else ldrb r3, [r1], #1 -#endif +# endif cmp r3, #0 beq .LC12 cmp r3, #' ' @@ -142,7 +148,7 @@ __change_mode: /* See whether we are scanning a string */ cmp r3, #'"' -#ifdef __thumb__ +# ifdef __thumb__ beq .LC20 cmp r3, #'\'' bne .LC21 @@ -154,27 +160,27 @@ __change_mode: mov r2, #' ' /* terminator type */ sub r1, r1, #1 /* adjust back to point at start char */ .LC22: -#else +# else cmpne r3, #'\'' moveq r2, r3 movne r2, #' ' /* terminator type */ subne r1, r1, #1 /* adjust back to point at start char */ -#endif +# endif /* Stack a pointer to the current argument */ -#ifdef __thumb__ +# ifdef __thumb__ push {r1} -#else +# else stmfd sp!, {r1} -#endif +# endif add r0, r0, #1 .LC11: -#ifdef __thumb__ +# ifdef __thumb__ ldrb r3, [r1] add r1, #1 -#else +# else ldrb r3, [r1], #1 -#endif +# endif cmp r3, #0 beq .LC12 cmp r2, r3 /* reached terminator? */ @@ -187,7 +193,7 @@ __change_mode: .LC12: mov r1, sp /* point at stacked arg pointers */ /* We've now got the stacked args in order reverse the */ -#ifdef __thumb__ +# ifdef __thumb__ mov r2, r0 lsl r2, #2 add r2, sp @@ -207,7 +213,7 @@ __change_mode: mov r5, #7 bic r4, r5 mov sp, r4 -#else +# else add r2, sp, r0, LSL #2 /* End of args */ mov r3, sp /* Start of args */ .LC13: cmp r2, r3 @@ -218,7 +224,7 @@ __change_mode: bhi .LC13 /* Ensure doubleword stack alignment. */ bic sp, sp, #7 -#endif +# endif #endif #ifdef __USES_INITFINI__ @@ -258,18 +264,20 @@ change_back: positive offsets are supported for PC relative addresses. */ .align 0 +#ifndef _ARM_V7M .LC0: -#ifdef ARM_RDI_MONITOR +# ifdef ARM_RDI_MONITOR .word HeapBase -#else -#ifndef ARM_RDP_MONITOR -#ifdef __pe__ +# else +# ifndef ARM_RDP_MONITOR +# ifdef __pe__ .word 0x800000 -#else +# else /* .word 0x80000 */ /* Top of RAM on the PIE board. */ -#endif -#endif -#endif +# endif +# endif +# endif +#endif #if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__) /* Protect against unhandled exceptions. */ .cantunwind @@ -283,7 +291,7 @@ change_back: .Lfini: .word FUNCTION(_fini) #endif -#ifdef ARM_RDI_MONITOR +#if defined(ARM_RDI_MONITOR) && !defined(_ARM_V7M) .LC30: .word CommandLine .word 255 @@ -303,3 +311,18 @@ CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */ .section .idata$3 .long 0,0,0,0,0,0,0,0 #endif + +#ifdef _ARM_V7M + /* The hardware uses this vector to handle hardware resets and + exceptions. */ + .section .isr_vector, "a" + /* The value for the stack pointer at reset. */ + .word _stack + /* The value for the PC at reset. */ + .word _start + /* The value for the PC if an NMI occurs. */ + .word _nmi_isr + /* The value for the PC if a fault occurs. */ + .word _fault_isr +#endif _ARM_V7M + diff --git a/newlib/libc/sys/arm/swi.h b/newlib/libc/sys/arm/swi.h index f5c910313..c5ba88343 100644 --- a/newlib/libc/sys/arm/swi.h +++ b/newlib/libc/sys/arm/swi.h @@ -66,3 +66,24 @@ #define AngelSWI_Reason_ReportException 0x18 #define ADP_Stopped_ApplicationExit ((2 << 16) + 38) #define ADP_Stopped_RunTimeError ((2 << 16) + 35) + +#if defined(ARM_RDI_MONITOR) && !defined(__ASSEMBLER__) + +extern inline int +do_AngelSWI (int reason, void * arg) +{ + int value; + asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0" + : "=r" (value) /* Outputs */ + : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */ + : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" + /* Clobbers r0 and r1, and lr if in supervisor mode */); + /* Accordingly to page 13-77 of ARM DUI 0040D other registers + can also be clobbered. Some memory positions may also be + changed by a system call, so they should not be kept in + registers. Note: we are assuming the manual is right and + Angel is respecting the APCS. */ + return value; +} + +#endif diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index 529309930..d465d4215 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -29,7 +29,6 @@ int _fstat _PARAMS ((int, struct stat *)); caddr_t _sbrk _PARAMS ((int)); int _getpid _PARAMS ((int)); int _kill _PARAMS ((int, int)); -void _exit _PARAMS ((int)); int _close _PARAMS ((int)); int _swiclose _PARAMS ((int)); int _open _PARAMS ((const char *, int, ...)); @@ -40,29 +39,17 @@ int _lseek _PARAMS ((int, int, int)); int _swilseek _PARAMS ((int, int, int)); int _read _PARAMS ((int, char *, int)); int _swiread _PARAMS ((int, char *, int)); -void initialise_monitor_handles _PARAMS ((void)); +static void initialise_monitor_handles _PARAMS ((void)); static int wrap _PARAMS ((int)); static int error _PARAMS ((int)); static int get_errno _PARAMS ((void)); static int remap_handle _PARAMS ((int)); -static int do_AngelSWI _PARAMS ((int, void *)); static int findslot _PARAMS ((int)); /* Register name faking - works in collusion with the linker. */ register char * stack_ptr asm ("sp"); - -/* following is copied from libc/stdio/local.h to check std streams */ -extern void _EXFUN(__sinit,(struct _reent *)); -#define CHECK_INIT(ptr) \ - do \ - { \ - if ((ptr) && !(ptr)->__sdidinit) \ - __sinit (ptr); \ - } \ - while (0) - /* Adjust our internal handles to stay away from std* handles. */ #define FILE_HANDLE_OFFSET (0x20) @@ -92,31 +79,11 @@ findslot (int fh) return i; } -#ifdef ARM_RDI_MONITOR - -static inline int -do_AngelSWI (int reason, void * arg) -{ - int value; - asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0" - : "=r" (value) /* Outputs */ - : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */ - : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" - /* Clobbers r0 and r1, and lr if in supervisor mode */); - /* Accordingly to page 13-77 of ARM DUI 0040D other registers - can also be clobbered. Some memory positions may also be - changed by a system call, so they should not be kept in - registers. Note: we are assuming the manual is right and - Angel is respecting the APCS. */ - return value; -} -#endif /* ARM_RDI_MONITOR */ - /* Function to convert std(in|out|err) handles to internal versions. */ static int remap_handle (int fh) { - CHECK_INIT(_REENT); + initialise_monitor_handles (); if (fh == STDIN_FILENO) return monitor_stdin; @@ -128,11 +95,28 @@ remap_handle (int fh) return fh - FILE_HANDLE_OFFSET; } +#ifndef __SINGLE_THREAD__ +__LOCK_INIT_RECURSIVE (static, __arm_monitor_handles_lock); +#endif + void initialise_monitor_handles (void) { int i; - + static int initialized; + + /* We need do this only once. */ + if (initialized) + return; + +#ifndef __SINGLE_THREAD__ + __lock_acquire_recursive (__arm_monitor_handles_lock); +#endif + initialized = 1; +#ifndef __SINGLE_THREAD__ + __lock_release_recursive (__arm_monitor_handles_lock); +#endif + #ifdef ARM_RDI_MONITOR int volatile block[3]; @@ -433,20 +417,6 @@ _close (int file) return wrap (_swiclose (file)); } -void -_exit (int n) -{ - /* FIXME: return code is thrown away. */ - -#ifdef ARM_RDI_MONITOR - do_AngelSWI (AngelSWI_Reason_ReportException, - (void *) ADP_Stopped_ApplicationExit); -#else - asm ("swi %a0" :: "i" (SWI_Exit)); -#endif - n = n; -} - int _kill (int n, int m) { |