This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: ARMV7M support


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]