2009-10-01 Joel Sherrill <joel.sherrill@oarcorp.com>

* .cvsignore, ChangeLog, Makefile.am, bsp_specs, configure.ac,
	preinstall.am, console/.cvsignore, console/console-io.c,
	include/.cvsignore, include/bsp.h, include/irq.h, include/swi.h,
	start/.cvsignore, start/start.S, startup/.cvsignore,
	startup/bspreset.c, startup/bspstart.c, startup/linkcmds,
	startup/syscalls.c: New files.
This commit is contained in:
Joel Sherrill
2009-10-01 21:48:42 +00:00
parent 13c5cea6e3
commit 44bb5cd0cb
19 changed files with 2059 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.log
config.status
configure

View File

@@ -0,0 +1,9 @@
2009-10-01 Joel Sherrill <joel.sherrill@oarcorp.com>
* .cvsignore, ChangeLog, Makefile.am, bsp_specs, configure.ac,
preinstall.am, console/.cvsignore, console/console-io.c,
include/.cvsignore, include/bsp.h, include/irq.h, include/swi.h,
start/.cvsignore, start/start.S, startup/.cvsignore,
startup/bspreset.c, startup/bspstart.c, startup/linkcmds,
startup/syscalls.c: New files.

View File

@@ -0,0 +1,55 @@
##
## $Id$
##
ACLOCAL_AMFLAGS = -I ../../../../aclocal
include $(top_srcdir)/../../../../automake/compile.am
include_bspdir = $(includedir)/bsp
dist_project_lib_DATA = bsp_specs
include_HEADERS = include/bsp.h
include_HEADERS += ../../shared/include/tm27.h
include_bsp_HEADERS = include/irq.h
include_bsp_HEADERS += include/swi.h
nodist_include_HEADERS = include/bspopts.h
nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
DISTCLEANFILES = include/bspopts.h
noinst_PROGRAMS =
nodist_include_HEADERS += ../../shared/include/coverhd.h
noinst_LIBRARIES = libbspstart.a
libbspstart_a_SOURCES = start/start.S
project_lib_DATA = start.$(OBJEXT)
dist_project_lib_DATA += startup/linkcmds
noinst_LIBRARIES += libbsp.a
libbsp_a_SOURCES =
# startup
libbsp_a_SOURCES += ../../shared/bsplibc.c ../../shared/bsppost.c \
../../shared/bspgetworkarea.c ../../shared/bsppretaskinghook.c \
../../shared/bsppredriverhook.c ../../shared/bspstart.c \
../../shared/bspclean.c startup/bspreset.c ../../shared/bootcard.c \
../../shared/sbrk.c ../../shared/gnatinstallhandler.c startup/syscalls.c
# console
libbsp_a_SOURCES += ../../shared/console-polled.c console/console-io.c
# clock
libbsp_a_SOURCES += ../../shared/clock_driver_simidle.c
# timer
libbsp_a_SOURCES += ../../shared/timerstub.c
# above
libbsp_a_SOURCES += ../shared/abort/abort.c
#libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/shared/arm920.rel \
# ../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/clock.rel \
# ../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/timer.rel \
# ../../../libcpu/@RTEMS_CPU@/@RTEMS_CPU_MODEL@/irq.rel
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am

View File

@@ -0,0 +1,14 @@
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*startfile:
%{!qrtems: %(old_startfile)} \
%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dp -Bstatic -N}
*endfile:
%{!qrtems: *(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s }

View File

@@ -0,0 +1,22 @@
## Process this file with autoconf to produce a configure script.
##
## configure.ac,v 1.5 2003/03/11 09:39:07 ralf Exp
AC_PREREQ(2.60)
AC_INIT([rtems-c-src-lib-libbsp-arm-gdbarmsim],[_RTEMS_VERSION],[rtems-bugs@OARcorp.com])
AC_CONFIG_SRCDIR([bsp_specs])
RTEMS_TOP(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.10])
RTEMS_BSP_CONFIGURE
RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
RTEMS_CANONICALIZE_TOOLS
RTEMS_PROG_CCAS
RTEMS_BSP_CLEANUP_OPTIONS(0, 1)
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.log
config.status
configure

View File

@@ -0,0 +1,61 @@
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <stdlib.h>
#include <assert.h>
/*
* console_initialize_hardware
*
* This routine initializes the console hardware.
*
*/
void console_initialize_hardware(void)
{
return;
}
int _write(int fd, char *ptr, int len);
/*
* console_outbyte_polled
*
* This routine transmits a character using polling.
*/
void console_outbyte_polled(
int port,
char ch
)
{
_write(2, &ch, 1);
}
/*
* console_inbyte_nonblocking
*
* This routine polls for a character.
*/
int console_inbyte_nonblocking(
int port
)
{
return -1;
}
#include <rtems/bspIo.h>
void MyBSP_output_char(char c) { console_outbyte_polled( 0, c ); }
BSP_output_char_function_type BSP_output_char = MyBSP_output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;

View File

@@ -0,0 +1,7 @@
Makefile
Makefile.in
coverhd.h
bspopts.h
bspopts.h.in
stamp-h
stamp-h.in

View File

@@ -0,0 +1,35 @@
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _BSP_H
#define _BSP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <bspopts.h>
#include <rtems.h>
#include <rtems/iosupp.h>
#include <rtems/console.h>
#include <rtems/clockdrv.h>
/* support for simulated clock tick */
Thread clock_driver_sim_idle_body(uintptr_t);
#define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
#ifdef __cplusplus
}
#endif
#endif /* _BSP_H */

View File

@@ -0,0 +1,94 @@
/**
* @file
*
* @ingroup bsp_interrupt
*
* @brief Dummy interrupt definitions.
*/
/*
* Copyright (c) 2008
* Embedded Brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
*
* The license and distribution terms for this file may be found in the file
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
*/
#ifndef LIBBSP_ARM_DUMMY_IRQ_H
#define LIBBSP_ARM_DUMMY_IRQ_H
#ifndef ASM
#include <rtems.h>
#include <rtems/irq.h>
#include <rtems/irq-extension.h>
/**
* @addtogroup bsp_interrupt
*
* @{
*/
#define DUMMY_IRQ_WDT 0
#define DUMMY_IRQ_SOFTWARE 1
#define DUMMY_IRQ_ARM_CORE_0 2
#define DUMMY_IRQ_ARM_CORE_1 3
#define DUMMY_IRQ_TIMER_0 4
#define DUMMY_IRQ_TIMER_1 5
#define DUMMY_IRQ_UART_0 6
#define DUMMY_IRQ_UART_1 7
#define DUMMY_IRQ_PWM 8
#define DUMMY_IRQ_I2C_0 9
#define DUMMY_IRQ_SPI_SSP_0 10
#define DUMMY_IRQ_SSP_1 11
#define DUMMY_IRQ_PLL 12
#define DUMMY_IRQ_RTC 13
#define DUMMY_IRQ_EINT_0 14
#define DUMMY_IRQ_EINT_1 15
#define DUMMY_IRQ_EINT_2 16
#define DUMMY_IRQ_EINT_3 17
#define DUMMY_IRQ_ADC_0 18
#define DUMMY_IRQ_I2C_1 19
#define DUMMY_IRQ_BOD 20
#define DUMMY_IRQ_ETHERNET 21
#define DUMMY_IRQ_USB 22
#define DUMMY_IRQ_CAN 23
#define DUMMY_IRQ_SD_MMC 24
#define DUMMY_IRQ_DMA 25
#define DUMMY_IRQ_TIMER_2 26
#define DUMMY_IRQ_TIMER_3 27
#define DUMMY_IRQ_UART_2 28
#define DUMMY_IRQ_UART_3 29
#define DUMMY_IRQ_I2C_2 30
#define DUMMY_IRQ_I2S 31
#define DUMMY_IRQ_PRIORITY_VALUE_MIN 0U
#define DUMMY_IRQ_PRIORITY_VALUE_MAX 15U
/**
* @brief Minimum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MIN DUMMY_IRQ_WDT
/**
* @brief Maximum vector number.
*/
#define BSP_INTERRUPT_VECTOR_MAX DUMMY_IRQ_I2S
void bsp_interrupt_dispatch( void);
#if 0
void lpc24xx_irq_set_priority( rtems_vector_number vector, unsigned priority);
unsigned lpc24xx_irq_priority( rtems_vector_number vector);
#endif
/** @} */
#endif /* ASM */
#endif /* LIBBSP_ARM_DUMMY_IRQ_H */

View File

@@ -0,0 +1,96 @@
/*
* Copied from libgloss 1 Oct 2009.
* Minor modifications to work with RTEMS.
*
* $Id$
*/
/* SWI numbers for RDP (Demon) monitor. */
#define SWI_WriteC 0x0
#define SWI_Write0 0x2
#define SWI_ReadC 0x4
#define SWI_CLI 0x5
#define SWI_GetEnv 0x10
#define SWI_Exit 0x11
#define SWI_EnterOS 0x16
#define SWI_GetErrno 0x60
#define SWI_Clock 0x61
#define SWI_Time 0x63
#define SWI_Remove 0x64
#define SWI_Rename 0x65
#define SWI_Open 0x66
#define SWI_Close 0x68
#define SWI_Write 0x69
#define SWI_Read 0x6a
#define SWI_Seek 0x6b
#define SWI_Flen 0x6c
#define SWI_IsTTY 0x6e
#define SWI_TmpNam 0x6f
#define SWI_InstallHandler 0x70
#define SWI_GenerateError 0x71
/* Now the SWI numbers and reason codes for RDI (Angel) monitors. */
#define AngelSWI_ARM 0x123456
#ifdef __thumb__
#define AngelSWI 0xAB
#else
#define AngelSWI AngelSWI_ARM
#endif
/* For Thumb-2 code use the BKPT instruction instead of SWI. */
#ifdef __thumb2__
#define AngelSWIInsn "bkpt"
#define AngelSWIAsm bkpt
#else
#define AngelSWIInsn "swi"
#define AngelSWIAsm swi
#endif
/* The reason codes: */
#define AngelSWI_Reason_Open 0x01
#define AngelSWI_Reason_Close 0x02
#define AngelSWI_Reason_WriteC 0x03
#define AngelSWI_Reason_Write0 0x04
#define AngelSWI_Reason_Write 0x05
#define AngelSWI_Reason_Read 0x06
#define AngelSWI_Reason_ReadC 0x07
#define AngelSWI_Reason_IsTTY 0x09
#define AngelSWI_Reason_Seek 0x0A
#define AngelSWI_Reason_FLen 0x0C
#define AngelSWI_Reason_TmpNam 0x0D
#define AngelSWI_Reason_Remove 0x0E
#define AngelSWI_Reason_Rename 0x0F
#define AngelSWI_Reason_Clock 0x10
#define AngelSWI_Reason_Time 0x11
#define AngelSWI_Reason_System 0x12
#define AngelSWI_Reason_Errno 0x13
#define AngelSWI_Reason_GetCmdLine 0x15
#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__)
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

View File

@@ -0,0 +1,75 @@
## Automatically generated by ampolish3 - Do not edit
if AMPOLISH3
$(srcdir)/preinstall.am: Makefile.am
$(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am
endif
PREINSTALL_DIRS =
DISTCLEANFILES += $(PREINSTALL_DIRS)
all-local: $(TMPINSTALL_FILES)
TMPINSTALL_FILES =
CLEANFILES = $(TMPINSTALL_FILES)
all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES += $(PREINSTALL_FILES)
$(PROJECT_LIB)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_LIB)
@: > $(PROJECT_LIB)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_INCLUDE)/bsp/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/bsp
@: > $(PROJECT_INCLUDE)/bsp/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
$(PROJECT_INCLUDE)/bsp/swi.h: include/swi.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/swi.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/swi.h
$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h
$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT)
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds

View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.log
config.status
configure

View File

@@ -0,0 +1,403 @@
/*
* Copied from libgloss 1 Oct 2009.
* Minor modifications to work with RTEMS.
*
* $Id$
*/
#include <newlib.h>
#include <bsp/swi.h>
/* ANSI concatenation macros. */
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
#ifdef __USER_LABEL_PREFIX__
#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
#else
#error __USER_LABEL_PREFIX is not defined
#endif
#ifdef HAVE_INITFINI_ARRAY
#define _init __libc_init_array
#define _fini __libc_fini_array
#endif
/* .text is used instead of .section .text so it works with arm-aout too. */
.text
#if defined(__thumb2__)
.syntax unified
.thumb
.macro FUNC_START name
.global \name
.thumb_func
\name:
.endm
#else
.code 32
.macro FUNC_START name
.global \name
\name:
.endm
#endif
.align 0
FUNC_START _mainCRTStartup
FUNC_START _start
FUNC_START start
#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 */
/* Changes by toralf:
- Allow linker script to provide stack via __stack symbol - see
defintion of .Lstack
- Provide "hooks" that may be used by the application to add
custom init code - see .Lhwinit and .Lswinit
- Go through all execution modes and set up stack for each of them.
Loosely based on init.s from ARM/Motorola example code.
Note: Mode switch via CPSR is not allowed once in non-privileged
mode, so we take care not to enter "User" to set up its sp,
and also skip most operations if already in that mode. */
ldr r3, .Lstack
cmp r3, #0
#ifdef __thumb2__
it eq
#endif
ldreq r3, .LC0
/* Note: This 'mov' is essential when starting in User, and ensures we
always get *some* sp value for the initial mode, even if we
have somehow missed it below (in which case it gets the same
value as FIQ - not ideal, but better than nothing.) */
mov sp, r3
#ifdef __thumb2__
/* XXX Fill in stack assignments for interrupt modes. */
#else
mrs r2, CPSR
tst r2, #0x0F /* Test mode bits - in User of all are 0 */
beq .LC23 /* "eq" means r2 AND #0x0F is 0 */
msr CPSR_c, #0xD1 /* FIRQ mode, interrupts disabled */
mov sp, r3
sub sl, sp, #0x1000 /* This mode also has its own sl (see below) */
mov r3, sl
msr CPSR_c, #0xD7 /* Abort mode, interrupts disabled */
mov sp, r3
sub r3, r3, #0x1000
msr CPSR_c, #0xDB /* Undefined mode, interrupts disabled */
mov sp, r3
sub r3, r3, #0x1000
msr CPSR_c, #0xD2 /* IRQ mode, interrupts disabled */
mov sp, r3
sub r3, r3, #0x2000
msr CPSR_c, #0xD3 /* Supervisory mode, interrupts disabled */
mov sp, r3
sub r3, r3, #0x8000 /* Min size 32k */
bic r3, r3, #0x00FF /* Align with current 64k block */
bic r3, r3, #0xFF00
str r3, [r3, #-4] /* Move value into user mode sp without */
ldmdb r3, {sp}^ /* changing modes, via '^' form of ldm */
orr r2, r2, #0xC0 /* Back to original mode, presumably SVC, */
msr CPSR_c, r2 /* with FIQ/IRQ disable bits forced to 1 */
#endif
.LC23:
/* Setup a default stack-limit in-case the code has been
compiled with "-mapcs-stack-check". Hard-wiring this value
is not ideal, since there is currently no support for
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, r3, #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 */
ldr a1, .LC1 /* First arg: start of memory block */
ldr a3, .LC2
sub a3, a3, a1 /* Third arg: length of block */
#if defined(__thumb__) && !defined(__thumb2__)
/* Enter Thumb mode.... */
add a4, pc, #1 /* Get the address of the Thumb block */
bx a4 /* Go there and start Thumb decoding */
.code 16
.global __change_mode
.thumb_func
__change_mode:
#endif
bl FUNCTION (memset)
#if !defined (ARM_RDP_MONITOR) && !defined (ARM_RDI_MONITOR)
/* Changes by toralf: Taken from libgloss/m68k/crt0.S
* initialize target specific stuff. Only execute these
* functions it they exist.
*/
ldr r3, .Lhwinit
cmp r3, #0
beq .LC24
#if defined(__thumb__) || defined(__thumb2__)
blx r3
#else
mov lr, pc
mov pc, r3
#endif
.LC24:
ldr r3, .Lswinit
cmp r3, #0
beq .LC25
#if defined(__thumb__) || defined(__thumb2__)
blx r3
#else
mov lr, pc
mov pc, r3
#endif
.LC25:
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
b .LC22
.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
sub r3, r1, #1
strb r2, [r3] /* terminate the arg string */
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
bls .LC14
sub r2, #4
ldr r4, [r2]
ldr r5, [r3]
str r5, [r2]
str r4, [r3]
add r3, #4
b .LC15
.LC14:
/* 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
bl FUNCTION (boot_card)
bl FUNCTION (bsp_cleanup) /* Should not return. */
#if defined(__thumb__) && !defined(__thumb2__)
/* Come out of Thumb mode. This code should be redundant. */
mov a4, pc
bx a4
.code 32
.global change_back
change_back:
/* Halt the execution. This code should never be executed. */
/* With no debug monitor, this probably aborts (eventually).
With a Demon debug monitor, this halts cleanly.
With an Angel debug monitor, this will report 'Unknown SWI'. */
swi SWI_Exit
#endif
/* 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
/* Changes by toralf: Provide alternative "stack" variable whose value
may be defined externally; .Lstack will be used instead of .LC0 if
it points to a non-0 value. Also set up references to "hooks" that
may be used by the application to provide additional init code. */
#ifdef __pe__
.word 0x800000
#else
.word 0x80000 /* Top of RAM on the PIE board. */
#endif
.Lstack:
.word __stack
.Lhwinit:
.word FUNCTION (hardware_init_hook)
.Lswinit:
.word FUNCTION (software_init_hook)
/* Set up defaults for the above variables in the form of weak symbols
- so that application will link correctly, and get value 0 in
runtime (meaning "ignore setting") for the variables, when the user
does not provide the symbols. (The linker uses a weak symbol if,
and only if, a normal version of the same symbol isn't provided
e.g. by a linker script or another object file.) */
.weak __stack
.weak FUNCTION (hardware_init_hook)
.weak FUNCTION (software_init_hook)
#endif
#endif
#if defined(__ELF__) && !defined(__USING_SJLJ_EXCEPTIONS__)
/* Protect against unhandled exceptions. */
.cantunwind
.fnend
#endif
.LC1:
.word __bss_start__
.LC2:
.word __clear_end__ /* __bss_end__ */
#ifdef __USES_INITFINI__
.Lfini:
.word FUNCTION(_fini)
#endif
#ifdef ARM_RDI_MONITOR
.LC30:
.word CommandLine
.word 255
/* Workspace for Angel calls. */
.data
/* Data returned by monitor SWI. */
.global __stack_base__
HeapBase: .word 0
HeapLimit: .word 0
__stack_base__: .word 0
StackLimit: .word 0
CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */
#endif
#ifdef __pe__
.section .idata$3
.long 0,0,0,0,0,0,0,0
#endif

View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.log
config.status
configure

View File

@@ -0,0 +1,19 @@
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <bsp/bootcard.h>
#include <bsp/swi.h>
void bsp_reset( void )
{
asm ("swi %a0" :: "i" (SWI_Exit));
}

View File

@@ -0,0 +1,24 @@
/*
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <bsp.h>
#include <bsp/bootcard.h>
void initialise_monitor_handles(void);
/*
* This routine would usually do the bulk of the system initialization.
* But if a BSP doesn't need to do anything, it can use this version.
*/
void bsp_start( void )
{
initialise_monitor_handles(void);
}

View File

@@ -0,0 +1,252 @@
/*
* Cogent CSB336 Linker script
*
* Copyright (c) 2004 by Cogent Computer Systems
* Written by Jay Monkman <jtm@lopingdog.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/* SEARCH_DIR(/usr/local/rtems-arm-dev-tools/arm-rtems/lib); */
MEMORY {
sdram : ORIGIN = 0x00000000, LENGTH = 4M
}
/*
* Declare some sizes.
*/
/* The base for SDRAM is set to umon's APPRAMBASE */
_sdram_base = DEFINED(_sdram_base) ? _sdram_base : 0x0;
_sdram_size = DEFINED(_sdram_size) ? _sdram_size : 4M;
RamBase = _sdram_base;
RamSize = _sdram_size;
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0;
_irq_stack_size = DEFINED(_irq_stack_size) ? _irq_stack_size : 0x1000;
_fiq_stack_size = DEFINED(_fiq_stack_size) ? _fiq_stack_size : 0x400;
_abt_stack_size = DEFINED(_abt_stack_size) ? _abt_stack_size : 0x400;
_undef_stack_size = DEFINED(_undef_stack_size) ? _undef_stack_size : 0x400;
_svc_stack_size = DEFINED(_svc_stack_size) ? _svc_stack_size : 0x1000;
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
.base :
{
arm_exception_table = .;
arm_reset_vect = .; /* 0x00 */
. += 4;
arm_undef_vect = .; /* 0x04 */
. += 4;
arm_swi_vect = .; /* 0x08 */
. += 4;
arm_iabrt_vect = .; /* 0x0c */
. += 4;
arm_dabrt_vect = .; /* 0x10 */
. += 4;
/* no vector here */
. += 4;
arm_irq_vect = .; /* 0x18 */
. += 4;
arm_fiq_vect = .; /* 0x1c */
. += 4;
/* FIXME: */
rtems_vector_table = .;
. += (8 * 4); /* 8 ARM interrupts */
. = ALIGN (0x100);
} > sdram
.text :
{
. = 0x8000;
_text_start = .;
CREATE_OBJECT_SYMBOLS
*(.text)
*(.text.*)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
/* I think these come from the ld docs: */
___CTOR_LIST__ = .;
LONG((___CTOR_END__ - ___CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
___CTOR_END__ = .;
___DTOR_LIST__ = .;
LONG((___DTOR_END__ - ___DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
___DTOR_END__ = .;
_etext = .;
PROVIDE (etext = .);
} > sdram
.init :
{
KEEP (*(.init))
} > sdram /*=0*/
.fini :
{
KEEP (*(.fini))
} > sdram /*=0*/
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
*(.jcr)
SORT(CONSTRUCTORS)
_edata = .;
} > sdram
.eh_frame : { *(.eh_frame) } > sdram
.data1 : { *(.data1) } > sdram
.eh_frame : { *(.eh_frame) } > sdram
.gcc_except_table : { *(.gcc_except_table*) } > sdram
.rodata :
{
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
} > sdram
.bss :
{
__bss_start__ = .;
_bss_start_ = .;
_clear_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(64);
_clear_end = .;
. = ALIGN (256);
_abt_stack = .;
. += _abt_stack_size;
. = ALIGN (256);
_undef_stack = .;
. += _undef_stack_size;
. = ALIGN (256);
_irq_stack = .;
. += _irq_stack_size;
. = ALIGN (256);
_fiq_stack = .;
. += _fiq_stack_size;
. = ALIGN (256);
_svc_stack = .;
. += _svc_stack_size;
/*
* Ideally, the MMU's translation table would be in SRAM. But we
* don't have any. If we don't use more regions than TLB entries (64),
* the lookup will only happen once for each region.
*/
. = ALIGN (16 * 1024);
_ttbl_base = .;
. += (16 * 1024);
. = ALIGN (1024);
_bss_free_start = .;
WorkAreaBase = .;
. = RamSize + RamBase - 1;
__clear_end__ = .;
__bss_end__ = .;
_bss_end_ = .;
_end = .;
__end = .;
} > sdram
/* Debugging stuff follows? */
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/*.stack 0x80000 : { _stack = .; *(.stack) }*/
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,861 @@
/*
* Copied from libgloss 1 Oct 2009.
* Minor modifications to work with RTEMS.
*
* $Id$
*/
/* Support files for GNU libc. Files in the system namespace go here.
Files in the C namespace (ie those that do not start with an
underscore) go in .c. */
#include <_ansi.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <errno.h>
#include <reent.h>
#include <unistd.h>
#include <sys/wait.h>
#include <bsp/swi.h>
/* Forward prototypes. */
int _system _PARAMS ((const char *));
int _rename _PARAMS ((const char *, const char *));
int _isatty _PARAMS ((int));
clock_t _times _PARAMS ((struct tms *));
int _gettimeofday _PARAMS ((struct timeval *, void *));
int _unlink _PARAMS ((const char *));
int _link _PARAMS ((void));
int _stat _PARAMS ((const char *, struct stat *));
int _fstat _PARAMS ((int, struct stat *));
int _swistat _PARAMS ((int fd, struct stat * st));
caddr_t _sbrk _PARAMS ((int));
int _getpid _PARAMS ((int));
int _close _PARAMS ((int));
clock_t _clock _PARAMS ((void));
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 checkerror _PARAMS ((int));
static int error _PARAMS ((int));
static int get_errno _PARAMS ((void));
/* Struct used to keep track of the file position, just so we
can implement fseek(fh,x,SEEK_CUR). */
struct fdent
{
int handle;
int pos;
};
#define MAX_OPEN_FILES 20
/* User file descriptors (fd) are integer indexes into
the openfiles[] array. Error checking is done by using
findslot().
This openfiles array is manipulated directly by only
these 5 functions:
findslot() - Translate entry.
newslot() - Find empty entry.
initilise_monitor_handles() - Initialize entries.
_swiopen() - Initialize entry.
_close() - Handle stdout == stderr case.
Every other function must use findslot(). */
static struct fdent openfiles [MAX_OPEN_FILES];
static struct fdent* findslot _PARAMS ((int));
static int newslot _PARAMS ((void));
/* 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)
static int monitor_stdin;
static int monitor_stdout;
static int monitor_stderr;
/* Return a pointer to the structure associated with
the user file descriptor fd. */
static struct fdent*
findslot (int fd)
{
CHECK_INIT(_REENT);
/* User file descriptor is out of range. */
if ((unsigned int)fd >= MAX_OPEN_FILES)
return NULL;
/* User file descriptor is open? */
if (openfiles[fd].handle == -1)
return NULL;
/* Valid. */
return &openfiles[fd];
}
/* Return the next lowest numbered free file
structure, or -1 if we can't find one. */
static int
newslot (void)
{
int i;
for (i = 0; i < MAX_OPEN_FILES; i++)
if (openfiles[i].handle == -1)
break;
if (i == MAX_OPEN_FILES)
return -1;
return i;
}
void
initialise_monitor_handles (void)
{
int i;
/* Open the standard file descriptors by opening the special
* teletype device, ":tt", read-only to obtain a descritpor for
* standard input and write-only to obtain a descriptor for standard
* output. Finally, open ":tt" in append mode to obtain a descriptor
* for standard error. Since this is a write mode, most kernels will
* probably return the same value as for standard output, but the
* kernel can differentiate the two using the mode flag and return a
* different descriptor for standard error.
*/
#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 = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
block[0] = (int) ":tt";
block[2] = 3; /* length of filename */
block[1] = 8; /* mode "a" */
monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
#else
int fh;
const char * name;
name = ":tt";
asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(name)
: "r0","r1");
monitor_stdin = fh;
name = ":tt";
asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(name)
: "r0","r1");
monitor_stdout = fh;
name = ":tt";
asm ("mov r0,%2; mov r1, #8; swi %a1; mov %0, r0"
: "=r"(fh)
: "i" (SWI_Open),"r"(name)
: "r0","r1");
monitor_stderr = fh;
#endif
/* If we failed to open stderr, redirect to stdout. */
if (monitor_stderr == -1)
monitor_stderr = monitor_stdout;
for (i = 0; i < MAX_OPEN_FILES; i ++)
openfiles[i].handle = -1;
openfiles[0].handle = monitor_stdin;
openfiles[0].pos = 0;
openfiles[1].handle = monitor_stdout;
openfiles[1].pos = 0;
openfiles[2].handle = monitor_stderr;
openfiles[2].pos = 0;
}
static int
get_errno (void)
{
#ifdef ARM_RDI_MONITOR
return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
#else
register int r0 asm("r0");
asm ("swi %a1" : "=r"(r0) : "i" (SWI_GetErrno));
return r0;
#endif
}
/* Set errno and return result. */
static int
error (int result)
{
errno = get_errno ();
return result;
}
/* Check the return and set errno appropriately. */
static int
checkerror (int result)
{
if (result == -1)
return error (-1);
return result;
}
/* fh, is a valid internal file handle.
ptr, is a null terminated string.
len, is the length in bytes to read.
Returns the number of bytes *not* written. */
int
_swiread (int fh,
char * ptr,
int len)
{
#ifdef ARM_RDI_MONITOR
int block[3];
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
return checkerror (do_AngelSWI (AngelSWI_Reason_Read, block));
#else
register int r0 asm("r0");
register int r1 asm("r1");
register int r2 asm("r2");
r0 = fh;
r1 = (int)ptr;
r2 = len;
asm ("swi %a4"
: "=r" (r0)
: "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Read));
return checkerror (r0);
#endif
}
/* fd, is a valid user file handle.
Translates the return of _swiread into
bytes read. */
int
_read (int fd,
char * ptr,
int len)
{
int res;
struct fdent *pfd;
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
res = _swiread (pfd->handle, ptr, len);
if (res == -1)
return res;
pfd->pos += len - res;
/* res == len is not an error,
at least if we want feof() to work. */
return len - res;
}
/* fd, is a user file descriptor. */
int
_swilseek (int fd,
int ptr,
int dir)
{
int res;
struct fdent *pfd;
/* Valid file descriptor? */
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
/* Valid whence? */
if ((dir != SEEK_CUR)
&& (dir != SEEK_SET)
&& (dir != SEEK_END))
{
errno = EINVAL;
return -1;
}
/* Convert SEEK_CUR to SEEK_SET */
if (dir == SEEK_CUR)
{
ptr = pfd->pos + ptr;
/* The resulting file offset would be negative. */
if (ptr < 0)
{
errno = EINVAL;
if ((pfd->pos > 0) && (ptr > 0))
errno = EOVERFLOW;
return -1;
}
dir = SEEK_SET;
}
#ifdef ARM_RDI_MONITOR
int block[2];
if (dir == SEEK_END)
{
block[0] = pfd->handle;
res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, block));
if (res == -1)
return -1;
ptr += res;
}
/* This code only does absolute seeks. */
block[0] = pfd->handle;
block[1] = ptr;
res = checkerror (do_AngelSWI (AngelSWI_Reason_Seek, block));
#else
if (dir == SEEK_END)
{
asm ("mov r0, %2; swi %a1; mov %0, r0"
: "=r" (res)
: "i" (SWI_Flen), "r" (pfd->handle)
: "r0");
checkerror (res);
if (res == -1)
return -1;
ptr += res;
}
/* This code only does absolute seeks. */
asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
: "=r" (res)
: "i" (SWI_Seek), "r" (pfd->handle), "r" (ptr)
: "r0", "r1");
checkerror (res);
#endif
/* At this point ptr is the current file position. */
if (res >= 0)
{
pfd->pos = ptr;
return ptr;
}
else
return -1;
}
int
_lseek (int fd,
int ptr,
int dir)
{
return _swilseek (fd, ptr, dir);
}
/* fh, is a valid internal file handle.
Returns the number of bytes *not* written. */
int
_swiwrite (
int fh,
char * ptr,
int len)
{
#ifdef ARM_RDI_MONITOR
int block[3];
block[0] = fh;
block[1] = (int) ptr;
block[2] = len;
return checkerror (do_AngelSWI (AngelSWI_Reason_Write, block));
#else
register int r0 asm("r0");
register int r1 asm("r1");
register int r2 asm("r2");
r0 = fh;
r1 = (int)ptr;
r2 = len;
asm ("swi %a4"
: "=r" (r0)
: "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Write));
return checkerror (r0);
#endif
}
/* fd, is a user file descriptor. */
int
_write (int fd,
char * ptr,
int len)
{
int res;
struct fdent *pfd;
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
res = _swiwrite (pfd->handle, ptr,len);
/* Clearly an error. */
if (res < 0)
return -1;
pfd->pos += len - res;
/* We wrote 0 bytes?
Retrieve errno just in case. */
if ((len - res) == 0)
return error (0);
return (len - res);
}
int
_swiopen (const char * path, int flags)
{
int aflags = 0, fh;
#ifdef ARM_RDI_MONITOR
int block[3];
#endif
int fd = newslot ();
if (fd == -1)
{
errno = EMFILE;
return -1;
}
/* It is an error to open a file that already exists. */
if ((flags & O_CREAT)
&& (flags & O_EXCL))
{
struct stat st;
int res;
res = _stat (path, &st);
if (res != -1)
{
errno = EEXIST;
return -1;
}
}
/* The flags are Unix-style, so we need to convert them. */
#ifdef O_BINARY
if (flags & O_BINARY)
aflags |= 1;
#endif
/* In O_RDONLY we expect aflags == 0. */
if (flags & O_RDWR)
aflags |= 2;
if ((flags & O_CREAT)
|| (flags & O_TRUNC)
|| (flags & O_WRONLY))
aflags |= 4;
if (flags & O_APPEND)
{
/* Can't ask for w AND a; means just 'a'. */
aflags &= ~4;
aflags |= 8;
}
#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)
: "r0","r1");
#endif
/* Return a user file descriptor or an error. */
if (fh >= 0)
{
openfiles[fd].handle = fh;
openfiles[fd].pos = 0;
return fd;
}
else
return error (fh);
}
int
_open (const char * path, int flags, ...)
{
return _swiopen (path, flags);
}
/* fh, is a valid internal file handle. */
int
_swiclose (int fh)
{
#ifdef ARM_RDI_MONITOR
return checkerror (do_AngelSWI (AngelSWI_Reason_Close, &fh));
#else
register int r0 asm("r0");
r0 = fh;
asm ("swi %a2"
: "=r"(r0)
: "0"(r0), "i" (SWI_Close));
return checkerror (r0);
#endif
}
/* fd, is a user file descriptor. */
int
_close (int fd)
{
int res;
struct fdent *pfd;
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
/* Handle stderr == stdout. */
if ((fd == 1 || fd == 2)
&& (openfiles[1].handle == openfiles[2].handle))
{
pfd->handle = -1;
return 0;
}
/* Attempt to close the handle. */
res = _swiclose (pfd->handle);
/* Reclaim handle? */
if (res == 0)
pfd->handle = -1;
return res;
}
int __attribute__((weak))
_getpid (int n __attribute__ ((unused)))
{
return 1;
}
#if !defined(__rtems__)
caddr_t
_sbrk (int incr)
{
extern char end asm ("end"); /* Defined by the linker. */
static char * heap_end;
char * prev_heap_end;
if (heap_end == NULL)
heap_end = & end;
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr)
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */
#if 0
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
errno = ENOMEM;
return (caddr_t) -1;
#endif
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
#endif
int
_swistat (int fd, struct stat * st)
{
struct fdent *pfd;
int res;
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
/* Always assume a character device,
with 1024 byte blocks. */
st->st_mode |= S_IFCHR;
st->st_blksize = 1024;
#ifdef ARM_RDI_MONITOR
res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle));
#else
asm ("mov r0, %2; swi %a1; mov %0, r0"
: "=r" (res)
: "i" (SWI_Flen), "r" (pfd->handle)
: "r0");
checkerror (res);
#endif
if (res == -1)
return -1;
/* Return the file size. */
st->st_size = res;
return 0;
}
int __attribute__((weak))
_fstat (int fd, struct stat * st)
{
memset (st, 0, sizeof (* st));
return _swistat (fd, st);
}
int __attribute__((weak))
_stat (const char *fname, struct stat *st)
{
int fd, res;
memset (st, 0, sizeof (* st));
/* The best we can do is try to open the file readonly.
If it exists, then we can guess a few things about it. */
if ((fd = _open (fname, O_RDONLY)) == -1)
return -1;
st->st_mode |= S_IFREG | S_IREAD;
res = _swistat (fd, st);
/* Not interested in the error. */
_close (fd);
return res;
}
int __attribute__((weak))
_link (void)
{
errno = ENOSYS;
return -1;
}
int
_unlink (const char *path)
{
int res;
#ifdef ARM_RDI_MONITOR
int block[2];
block[0] = (int)path;
block[1] = strlen(path);
res = do_AngelSWI (AngelSWI_Reason_Remove, block);
#else
register int r0 asm("r0");
r0 = (int)path;
asm ("swi %a2"
: "=r"(r0)
: "0"(r0), "i" (SWI_Remove));
res = r0;
#endif
if (res == -1)
return error (res);
return 0;
}
#if !defined(__rtems__)
int
_gettimeofday (struct timeval * tp, void * tzvp)
{
struct timezone *tzp = tzvp;
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;
}
#endif
tp->tv_usec = 0;
}
/* Return fixed data for the timezone. */
if (tzp)
{
tzp->tz_minuteswest = 0;
tzp->tz_dsttime = 0;
}
return 0;
}
#endif
/* Return a clock that ticks at 100Hz. */
clock_t
_clock (void)
{
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
return timeval;
}
/* Return a clock that ticks at 100Hz. */
clock_t
_times (struct tms * tp)
{
clock_t timeval = _clock();
if (tp)
{
tp->tms_utime = timeval; /* user time */
tp->tms_stime = 0; /* system time */
tp->tms_cutime = 0; /* user time, children */
tp->tms_cstime = 0; /* system time, children */
}
return timeval;
};
int
_isatty (int fd)
{
struct fdent *pfd;
pfd = findslot (fd);
if (pfd == NULL)
{
errno = EBADF;
return -1;
}
#ifdef ARM_RDI_MONITOR
return checkerror (do_AngelSWI (AngelSWI_Reason_IsTTY, &pfd->handle));
#else
register int r0 asm("r0");
r0 = pfd->handle;
asm ("swi %a2"
: "=r" (r0)
: "0"(r0), "i" (SWI_IsTTY));
return checkerror (r0);
#endif
}
int
_system (const char *s)
{
#ifdef ARM_RDI_MONITOR
int block[2];
int e;
/* Hmmm. The ARM debug interface specification doesn't say whether
SYS_SYSTEM does the right thing with a null argument, or assign any
meaning to its return value. Try to do something reasonable.... */
if (!s)
return 1; /* maybe there is a shell available? we can hope. :-P */
block[0] = (int)s;
block[1] = strlen (s);
e = checkerror (do_AngelSWI (AngelSWI_Reason_System, block));
if ((e >= 0) && (e < 256))
{
/* We have to convert e, an exit status to the encoded status of
the command. To avoid hard coding the exit status, we simply
loop until we find the right position. */
int exit_code;
for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1)
continue;
}
return e;
#else
register int r0 asm("r0");
r0 = (int)s;
asm ("swi %a2"
: "=r" (r0)
: "0"(r0), "i" (SWI_CLI));
return checkerror (r0);
#endif
}
int
_rename (const char * oldpath, const char * newpath)
{
#ifdef ARM_RDI_MONITOR
int block[4];
block[0] = (int)oldpath;
block[1] = strlen(oldpath);
block[2] = (int)newpath;
block[3] = strlen(newpath);
return checkerror (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
#else
register int r0 asm("r0");
register int r1 asm("r1");
r0 = (int)oldpath;
r1 = (int)newpath;
asm ("swi %a3"
: "=r" (r0)
: "0" (r0), "r" (r1), "i" (SWI_Rename));
return checkerror (r0);
#endif
}