This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
PATCH: ARMV7M support
- From: Mark Mitchell <mark at codesourcery dot com>
- To: newlib at sources dot redhat dot com
- Date: Thu, 23 Mar 2006 12:14:53 -0800
- Subject: PATCH: ARMV7M support
- Reply-to: mark at codesourcery dot com
This patch adds support for ARM V7M bare metal hardware to Newlib.
Here are the changes:
1. A new configure option --enable-newlib-arm-v7m. When this option
is in effect, crt0.S does not make use of RDI to get the stack
pointer, or make any other RDI calls during startup. That
eliminates access to the command-line, etc., but it also makes it
possible to use crt0.o without semihosting support.
2. Adds an ARM V7M interrupt service routine vector and provides
default contents for the vector. (Support for mapping that at the
correct requires a linker script, which I will post separately.)
3. Avoids calling initialise_monitor_handlers from _start. That
avoids pulling in all of syscalls.c into every program, and, since
syscalls.c depends on RDI, avoids pulling in RDI support. Instead,
we initialise_monitor_handles in remap_handles, which is where we
actually need the handles initialised. It's true that this means
that we make an extra function call on every use of remap_handles,
but since this function is only used when semihosting, a few extra
cycles don't matter.
For reasons I don't understand, initialise_monitor_handles setup
stdio. I don't see why that is required, and removing that avoids
pulling in stdio for a program using _open.
4. Factors _exit out into a separate file. Every program needs _exit,
but not every program needs _open, etc. We could further factor
things, but many of the other system calls depend on at least some
common routines, and if you need _read, you probably do need _open
and _close, so there's less of a win.
If this is approved, I'll commit it to libgloss too, unless explicitly
told not to do so.
OK?
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-03-23 Mark Mitchell <mark@codesourcery.com>
* libc/sys/arm/Makefile.am (extra_objs): Add _exit.o _nmi_isr.o
_fault_isr.o swi.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/swi.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 (_angel_swi): New function.
* libc/sys/arm/syscalls.c (_exit): Remove.
(do_angelSWI): Replace with _angel_swi.
(CHECK_INIT): Remove.
(remap_handle): Call initialise_monitor_handles.
(__arm_monitor_handles_lock): New variable.
(initialise_monitor_handles): Make sure to run only once.
Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/Makefile.am,v
retrieving revision 1.5
diff -c -5 -p -r1.5 Makefile.am
*** Makefile.am 31 Aug 2005 20:39:43 -0000 1.5
--- Makefile.am 23 Mar 2006 20:01:41 -0000
*************** AUTOMAKE_OPTIONS = cygnus
*** 5,15 ****
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
noinst_LIBRARIES = lib.a
if MAY_SUPPLY_SYSCALLS
! extra_objs = libcfunc.o trap.o syscalls.o
else
extra_objs =
endif
lib_a_SOURCES = aeabi_atexit.c
--- 5,15 ----
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
noinst_LIBRARIES = lib.a
if MAY_SUPPLY_SYSCALLS
! extra_objs = libcfunc.o trap.o syscalls.o swi.o _exit.o _nmi_isr.o _fault_isr.o
else
extra_objs =
endif
lib_a_SOURCES = aeabi_atexit.c
Index: _exit.c
===================================================================
RCS file: _exit.c
diff -N _exit.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- _exit.c 23 Mar 2006 20:01:41 -0000
***************
*** 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
+ _angel_swi (AngelSWI_Reason_ReportException,
+ (void *) ADP_Stopped_ApplicationExit);
+ #else
+ asm ("swi %a0" :: "i" (SWI_Exit));
+ #endif
+ n = n;
+ }
Index: _fault_isr.c
===================================================================
RCS file: _fault_isr.c
diff -N _fault_isr.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- _fault_isr.c 23 Mar 2006 20:01:41 -0000
***************
*** 0 ****
--- 1,16 ----
+ #include "newlib.h"
+
+ #ifdef _ARM_V7M
+
+ /* Called when a hardware fault occurs. Users can replace this
+ function. */
+
+ __attribute__((interrupt)) void
+ _fault_isr()
+ {
+ /* Sit an endless loop so that the user can analyze the situation
+ from the debugger. */
+ while (1);
+ }
+
+ #endif
Index: _nmi_isr.c
===================================================================
RCS file: _nmi_isr.c
diff -N _nmi_isr.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- _nmi_isr.c 23 Mar 2006 20:01:41 -0000
***************
*** 0 ****
--- 1,16 ----
+ #include "newlib.h"
+
+ #ifdef _ARM_V7M
+
+ /* Called when a non-maskable interrupt occurs. Users can replace this
+ function. */
+
+ __attribute__((interrupt)) void
+ _nmi_isr()
+ {
+ /* Sit an endless loop so that the user can analyze the situation
+ from the debugger. */
+ while (1);
+ }
+
+ #endif
Index: configure.in
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/configure.in,v
retrieving revision 1.1.1.1
diff -c -5 -p -r1.1.1.1 configure.in
*** configure.in 17 Feb 2000 19:39:49 -0000 1.1.1.1
--- configure.in 23 Mar 2006 20:01:42 -0000
*************** AC_PREREQ(2.5)
*** 5,12 ****
--- 5,28 ----
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)
Index: crt0.S
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/crt0.S,v
retrieving revision 1.12
diff -c -5 -p -r1.12 crt0.S
*** crt0.S 7 Feb 2006 18:44:54 -0000 1.12
--- crt0.S 23 Mar 2006 20:01:42 -0000
***************
*** 41,75 ****
#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
/* Annotation for EABI unwinding tables. */
.fnstart
#endif
! /* Start by setting up a stack */
! #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
/* 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__)
bkpt AngelSWI
! #else
/* We are always in ARM mode for startup */
AngelSWIAsm AngelSWI_ARM
! #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
/* Set up the stack pointer to a fixed value */
ldr r3, .LC0
mov sp, r3
/* Setup a default stack-limit in-case the code has been
compiled with "-mapcs-stack-check". Hard-wiring this value
--- 41,78 ----
#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
/* Annotation for EABI unwinding tables. */
.fnstart
#endif
! /* 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
/* 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__)
bkpt AngelSWI
! # else
/* We are always in ARM mode for startup */
AngelSWIAsm AngelSWI_ARM
! # 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
/* Set up the stack pointer to a fixed value */
ldr r3, .LC0
mov sp, r3
/* Setup a default stack-limit in-case the code has been
compiled with "-mapcs-stack-check". Hard-wiring this value
***************
*** 77,88 ****
checking that the heap and stack have not collided, or that
this default 64k is enough for the program being executed.
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
/* Zero the memory in the .bss section. */
mov a2, #0 /* Second arg: fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */
--- 80,93 ----
checking that the heap and stack have not collided, or that
this default 64k is enough for the program being executed.
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
!
/* Zero the memory in the .bss section. */
mov a2, #0 /* Second arg: fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */
***************
*** 101,150 ****
.thumb_func
__change_mode:
#endif
bl FUNCTION (memset)
! #if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
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
swi SWI_GetEnv /* sets r0 to point to the command line */
mov r1, r0
! #else
mov r0, #AngelSWI_Reason_GetCmdLine
adr r1, .LC30 /* Space for command line */
AngelSWIAsm AngelSWI
ldr r1, .LC30
! #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__
push {r0}
! #else
stmfd sp!, {r0}
! #endif
.LC10:
/* Skip leading blanks */
! #ifdef __thumb__
ldrb r3, [r1]
add r1, #1
! #else
ldrb r3, [r1], #1
! #endif
cmp r3, #0
beq .LC12
cmp r3, #' '
beq .LC10
/* See whether we are scanning a string */
cmp r3, #'"'
! #ifdef __thumb__
beq .LC20
cmp r3, #'\''
bne .LC21
.LC20:
mov r2, r3
--- 106,156 ----
.thumb_func
__change_mode:
#endif
bl FUNCTION (memset)
! /* 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
! # ifdef ARM_RDP_MONITOR
swi SWI_GetEnv /* sets r0 to point to the command line */
mov r1, r0
! # else
mov r0, #AngelSWI_Reason_GetCmdLine
adr r1, .LC30 /* Space for command line */
AngelSWIAsm AngelSWI
ldr r1, .LC30
! # 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__
push {r0}
! # else
stmfd sp!, {r0}
! # endif
.LC10:
/* Skip leading blanks */
! # ifdef __thumb__
ldrb r3, [r1]
add r1, #1
! # else
ldrb r3, [r1], #1
! # endif
cmp r3, #0
beq .LC12
cmp r3, #' '
beq .LC10
/* See whether we are scanning a string */
cmp r3, #'"'
! # ifdef __thumb__
beq .LC20
cmp r3, #'\''
bne .LC21
.LC20:
mov r2, r3
*************** __change_mode:
*** 152,182 ****
.LC21:
mov r2, #' ' /* terminator type */
sub r1, r1, #1 /* adjust back to point at start char */
.LC22:
! #else
cmpne r3, #'\''
moveq r2, r3
movne r2, #' ' /* terminator type */
subne r1, r1, #1 /* adjust back to point at start char */
! #endif
/* Stack a pointer to the current argument */
! #ifdef __thumb__
push {r1}
! #else
stmfd sp!, {r1}
! #endif
add r0, r0, #1
.LC11:
! #ifdef __thumb__
ldrb r3, [r1]
add r1, #1
! #else
ldrb r3, [r1], #1
! #endif
cmp r3, #0
beq .LC12
cmp r2, r3 /* reached terminator? */
bne .LC11
mov r2, #0
--- 158,188 ----
.LC21:
mov r2, #' ' /* terminator type */
sub r1, r1, #1 /* adjust back to point at start char */
.LC22:
! # else
cmpne r3, #'\''
moveq r2, r3
movne r2, #' ' /* terminator type */
subne r1, r1, #1 /* adjust back to point at start char */
! # endif
/* Stack a pointer to the current argument */
! # ifdef __thumb__
push {r1}
! # else
stmfd sp!, {r1}
! # endif
add r0, r0, #1
.LC11:
! # ifdef __thumb__
ldrb r3, [r1]
add r1, #1
! # else
ldrb r3, [r1], #1
! # endif
cmp r3, #0
beq .LC12
cmp r2, r3 /* reached terminator? */
bne .LC11
mov r2, #0
*************** __change_mode:
*** 185,195 ****
b .LC10
.LC12:
mov r1, sp /* point at stacked arg pointers */
/* We've now got the stacked args in order reverse the */
! #ifdef __thumb__
mov r2, r0
lsl r2, #2
add r2, sp
mov r3, sp
.LC15: cmp r2, r3
--- 191,201 ----
b .LC10
.LC12:
mov r1, sp /* point at stacked arg pointers */
/* We've now got the stacked args in order reverse the */
! # ifdef __thumb__
mov r2, r0
lsl r2, #2
add r2, sp
mov r3, sp
.LC15: cmp r2, r3
*************** __change_mode:
*** 205,226 ****
/* Ensure doubleword stack alignment. */
mov r4, sp
mov r5, #7
bic r4, r5
mov sp, r4
! #else
add r2, sp, r0, LSL #2 /* End of args */
mov r3, sp /* Start of args */
.LC13: cmp r2, r3
ldrhi r4,[r2, #-4] /* Reverse ends of list */
ldrhi r5, [r3]
strhi r5, [r2, #-4]!
strhi r4, [r3], #4
bhi .LC13
/* Ensure doubleword stack alignment. */
bic sp, sp, #7
! #endif
#endif
#ifdef __USES_INITFINI__
/* Some arm/elf targets use the .init and .fini sections
to create constructors and destructors, and for these
--- 211,232 ----
/* Ensure doubleword stack alignment. */
mov r4, sp
mov r5, #7
bic r4, r5
mov sp, r4
! # else
add r2, sp, r0, LSL #2 /* End of args */
mov r3, sp /* Start of args */
.LC13: cmp r2, r3
ldrhi r4,[r2, #-4] /* Reverse ends of list */
ldrhi r5, [r3]
strhi r5, [r2, #-4]!
strhi r4, [r3], #4
bhi .LC13
/* Ensure doubleword stack alignment. */
bic sp, sp, #7
! # endif
#endif
#ifdef __USES_INITFINI__
/* Some arm/elf targets use the .init and .fini sections
to create constructors and destructors, and for these
*************** change_back:
*** 256,277 ****
/* For Thumb, constants must be after the code since only
positive offsets are supported for PC relative addresses. */
.align 0
.LC0:
! #ifdef ARM_RDI_MONITOR
.word HeapBase
! #else
! #ifndef ARM_RDP_MONITOR
! #ifdef __pe__
.word 0x800000
! #else
/* .word 0x80000 */ /* Top of RAM on the PIE board. */
! #endif
! #endif
! #endif
#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
/* Protect against unhandled exceptions. */
.cantunwind
.fnend
#endif
--- 262,285 ----
/* For Thumb, constants must be after the code since only
positive offsets are supported for PC relative addresses. */
.align 0
+ #ifndef _ARM_V7M
.LC0:
! # ifdef ARM_RDI_MONITOR
.word HeapBase
! # else
! # ifndef ARM_RDP_MONITOR
! # ifdef __pe__
.word 0x800000
! # else
/* .word 0x80000 */ /* Top of RAM on the PIE board. */
! # endif
! # endif
! # endif
! #endif
#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
/* Protect against unhandled exceptions. */
.cantunwind
.fnend
#endif
*************** change_back:
*** 281,291 ****
.word __bss_end__
#ifdef __USES_INITFINI__
.Lfini:
.word FUNCTION(_fini)
#endif
! #ifdef ARM_RDI_MONITOR
.LC30:
.word CommandLine
.word 255
/* Workspace for Angel calls. */
--- 289,299 ----
.word __bss_end__
#ifdef __USES_INITFINI__
.Lfini:
.word FUNCTION(_fini)
#endif
! #if defined(ARM_RDI_MONITOR) && !defined(_ARM_V7M)
.LC30:
.word CommandLine
.word 255
/* Workspace for Angel calls. */
*************** CommandLine: .space 256,0 /* Maximum le
*** 301,305 ****
--- 309,328 ----
#ifdef __pe__
.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
+
Index: libcfunc.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/libcfunc.c,v
retrieving revision 1.2
diff -c -5 -p -r1.2 libcfunc.c
*** libcfunc.c 7 Feb 2006 18:44:54 -0000 1.2
--- libcfunc.c 23 Mar 2006 20:01:42 -0000
***************
*** 5,35 ****
Note: These functions are in a seperate file so that OS providers can
overrride the system call stubs (defined in syscalls.c) without having
to provide libc funcitons as well. */
#include "swi.h"
- #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", "lr"
- /* Clobbers r0 and r1, and lr if in supervisor mode */);
- return value;
- }
- #endif /* ARM_RDI_MONITOR */
-
-
void
abort (void)
{
#ifdef ARM_RDI_MONITOR
! do_AngelSWI (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_RunTimeError);
#else
asm ("mov r0,#17\nswi %a0" :: "i" (SWI_Exit));
#endif
}
--- 5,19 ----
Note: These functions are in a seperate file so that OS providers can
overrride the system call stubs (defined in syscalls.c) without having
to provide libc funcitons as well. */
#include "swi.h"
void
abort (void)
{
#ifdef ARM_RDI_MONITOR
! _angel_swi (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_RunTimeError);
#else
asm ("mov r0,#17\nswi %a0" :: "i" (SWI_Exit));
#endif
}
Index: swi.c
===================================================================
RCS file: swi.c
diff -N swi.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- swi.c 23 Mar 2006 20:01:42 -0000
***************
*** 0 ****
--- 1,7 ----
+ /* This file exists to provide an out-of-line definition of _arm_swi. */
+
+ #define _ARM_SWI_INLINE /*Empty */
+
+ /* Provide the definition. */
+ #include "swi.h"
+
Index: swi.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/swi.h,v
retrieving revision 1.3
diff -c -5 -p -r1.3 swi.h
*** swi.h 7 Feb 2006 18:44:54 -0000 1.3
--- swi.h 23 Mar 2006 20:01:42 -0000
***************
*** 64,68 ****
--- 64,93 ----
#define AngelSWI_Reason_HeapInfo 0x16
#define AngelSWI_Reason_EnterSVC 0x17
#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__)
+
+ #ifndef _ARM_SWI_INLINE
+ # define _ARM_SWI_INLINE extern inline
+ #endif
+
+ _ARM_SWI_INLINE int
+ _angel_swi (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
Index: syscalls.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/sys/arm/syscalls.c,v
retrieving revision 1.11
diff -c -5 -p -r1.11 syscalls.c
*** syscalls.c 7 Feb 2006 18:44:54 -0000 1.11
--- syscalls.c 23 Mar 2006 20:01:42 -0000
*************** int _link _PARAMS ((void));
*** 27,70 ****
int _stat _PARAMS ((const char *, struct stat *));
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, ...));
int _swiopen _PARAMS ((const char *, int));
int _write _PARAMS ((int, char *, int));
int _swiwrite _PARAMS ((int, char *, int));
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 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)
static int monitor_stdin;
static int monitor_stdout;
--- 27,57 ----
int _stat _PARAMS ((const char *, struct stat *));
int _fstat _PARAMS ((int, struct stat *));
caddr_t _sbrk _PARAMS ((int));
int _getpid _PARAMS ((int));
int _kill _PARAMS ((int, int));
int _close _PARAMS ((int));
int _swiclose _PARAMS ((int));
int _open _PARAMS ((const char *, int, ...));
int _swiopen _PARAMS ((const char *, int));
int _write _PARAMS ((int, char *, int));
int _swiwrite _PARAMS ((int, char *, int));
int _lseek _PARAMS ((int, int, int));
int _swilseek _PARAMS ((int, int, int));
int _read _PARAMS ((int, char *, int));
int _swiread _PARAMS ((int, char *, int));
+ 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 findslot _PARAMS ((int));
/* Register name faking - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
/* Adjust our internal handles to stay away from std* handles. */
#define FILE_HANDLE_OFFSET (0x20)
static int monitor_stdin;
static int monitor_stdout;
*************** findslot (int fh)
*** 90,124 ****
if (openfiles[i].handle == fh)
break;
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);
if (fh == STDIN_FILENO)
return monitor_stdin;
if (fh == STDOUT_FILENO)
return monitor_stdout;
--- 77,91 ----
if (openfiles[i].handle == fh)
break;
return i;
}
/* Function to convert std(in|out|err) handles to internal versions. */
static int
remap_handle (int fh)
{
! initialise_monitor_handles ();
if (fh == STDIN_FILENO)
return monitor_stdin;
if (fh == STDOUT_FILENO)
return monitor_stdout;
*************** remap_handle (int fh)
*** 126,152 ****
return monitor_stderr;
return fh - FILE_HANDLE_OFFSET;
}
void
initialise_monitor_handles (void)
{
int i;
!
#ifdef ARM_RDI_MONITOR
int volatile block[3];
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 0; /* mode "r" */
! monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 4; /* mode "w" */
! monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
#else
int fh;
const char * name;
name = ":tt";
--- 93,136 ----
return monitor_stderr;
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];
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 0; /* mode "r" */
! monitor_stdin = _angel_swi (AngelSWI_Reason_Open, (void *) block);
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 4; /* mode "w" */
! monitor_stdout = monitor_stderr = _angel_swi (AngelSWI_Reason_Open, (void *) block);
#else
int fh;
const char * name;
name = ":tt";
*************** initialise_monitor_handles (void)
*** 175,185 ****
static int
get_errno (void)
{
#ifdef ARM_RDI_MONITOR
! return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
#else
asm ("swi %a0" :: "i" (SWI_GetErrno));
#endif
}
--- 159,169 ----
static int
get_errno (void)
{
#ifdef ARM_RDI_MONITOR
! return _angel_swi (AngelSWI_Reason_Errno, NULL);
#else
asm ("swi %a0" :: "i" (SWI_GetErrno));
#endif
}
*************** _swiread (int file,
*** 210,220 ****
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
! return do_AngelSWI (AngelSWI_Reason_Read, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
--- 194,204 ----
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
! return _angel_swi (AngelSWI_Reason_Read, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
*************** _swilseek (int file,
*** 261,277 ****
#ifdef ARM_RDI_MONITOR
if (dir == SEEK_END)
{
block[0] = fh;
! ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
}
/* This code only does absolute seeks. */
block[0] = remap_handle (file);
block[1] = ptr;
! res = do_AngelSWI (AngelSWI_Reason_Seek, block);
#else
if (dir == SEEK_END)
{
asm ("mov r0, %2; swi %a1; mov %0, r0"
: "=r" (res)
--- 245,261 ----
#ifdef ARM_RDI_MONITOR
if (dir == SEEK_END)
{
block[0] = fh;
! ptr += _angel_swi (AngelSWI_Reason_FLen, block);
}
/* This code only does absolute seeks. */
block[0] = remap_handle (file);
block[1] = ptr;
! res = _angel_swi (AngelSWI_Reason_Seek, block);
#else
if (dir == SEEK_END)
{
asm ("mov r0, %2; swi %a1; mov %0, r0"
: "=r" (res)
*************** _swiwrite (
*** 315,325 ****
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
! return do_AngelSWI (AngelSWI_Reason_Write, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
--- 299,309 ----
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
! return _angel_swi (AngelSWI_Reason_Write, block);
#else
asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
: /* No outputs */
: "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
: "r0","r1","r2");
*************** _swiopen (const char * path,
*** 383,393 ****
#ifdef ARM_RDI_MONITOR
block[0] = (int) path;
block[2] = strlen (path);
block[1] = aflags;
! fh = do_AngelSWI (AngelSWI_Reason_Open, block);
#else
asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(path),"r"(aflags)
--- 367,377 ----
#ifdef ARM_RDI_MONITOR
block[0] = (int) path;
block[2] = strlen (path);
block[1] = aflags;
! fh = _angel_swi (AngelSWI_Reason_Open, block);
#else
asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(path),"r"(aflags)
*************** _swiclose (int file)
*** 419,429 ****
if (slot != MAX_OPEN_FILES)
openfiles[slot].handle = -1;
#ifdef ARM_RDI_MONITOR
! return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
#else
asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
#endif
}
--- 403,413 ----
if (slot != MAX_OPEN_FILES)
openfiles[slot].handle = -1;
#ifdef ARM_RDI_MONITOR
! return _angel_swi (AngelSWI_Reason_Close, & myhan);
#else
asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
#endif
}
*************** int
*** 431,459 ****
_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)
{
#ifdef ARM_RDI_MONITOR
! return do_AngelSWI (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_ApplicationExit);
#else
asm ("swi %a0" :: "i" (SWI_Exit));
#endif
n = n; m = m;
--- 415,429 ----
_close (int file)
{
return wrap (_swiclose (file));
}
int
_kill (int n, int m)
{
#ifdef ARM_RDI_MONITOR
! return _angel_swi (AngelSWI_Reason_ReportException,
(void *) ADP_Stopped_ApplicationExit);
#else
asm ("swi %a0" :: "i" (SWI_Exit));
#endif
n = n; m = m;
*************** _gettimeofday (struct timeval * tp, stru
*** 551,561 ****
if (tp)
{
/* Ask the host for the seconds since the Unix epoch. */
#ifdef ARM_RDI_MONITOR
! tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);
#else
{
int value;
asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
tp->tv_sec = value;
--- 521,531 ----
if (tp)
{
/* Ask the host for the seconds since the Unix epoch. */
#ifdef ARM_RDI_MONITOR
! tp->tv_sec = _angel_swi (AngelSWI_Reason_Time,NULL);
#else
{
int value;
asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
tp->tv_sec = value;
*************** clock_t
*** 579,589 ****
_times (struct tms * tp)
{
clock_t timeval;
#ifdef ARM_RDI_MONITOR
! timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
#else
asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
#endif
if (tp)
--- 549,559 ----
_times (struct tms * tp)
{
clock_t timeval;
#ifdef ARM_RDI_MONITOR
! timeval = _angel_swi (AngelSWI_Reason_Clock,NULL);
#else
asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
#endif
if (tp)