From 44bb5cd0cb1fce60be0cf83d7a590c56169d3b31 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 1 Oct 2009 21:48:42 +0000 Subject: 2009-10-01 Joel Sherrill * .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. --- c/src/lib/libbsp/arm/gdbarmsim/.cvsignore | 8 + c/src/lib/libbsp/arm/gdbarmsim/ChangeLog | 9 + c/src/lib/libbsp/arm/gdbarmsim/Makefile.am | 55 ++ c/src/lib/libbsp/arm/gdbarmsim/bsp_specs | 14 + c/src/lib/libbsp/arm/gdbarmsim/configure.ac | 22 + c/src/lib/libbsp/arm/gdbarmsim/console/.cvsignore | 8 + .../lib/libbsp/arm/gdbarmsim/console/console-io.c | 61 ++ c/src/lib/libbsp/arm/gdbarmsim/include/.cvsignore | 7 + c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h | 35 + c/src/lib/libbsp/arm/gdbarmsim/include/irq.h | 94 +++ c/src/lib/libbsp/arm/gdbarmsim/include/swi.h | 96 +++ c/src/lib/libbsp/arm/gdbarmsim/preinstall.am | 75 ++ c/src/lib/libbsp/arm/gdbarmsim/start/.cvsignore | 8 + c/src/lib/libbsp/arm/gdbarmsim/start/start.S | 403 ++++++++++ c/src/lib/libbsp/arm/gdbarmsim/startup/.cvsignore | 8 + c/src/lib/libbsp/arm/gdbarmsim/startup/bspreset.c | 19 + c/src/lib/libbsp/arm/gdbarmsim/startup/bspstart.c | 24 + c/src/lib/libbsp/arm/gdbarmsim/startup/linkcmds | 252 ++++++ c/src/lib/libbsp/arm/gdbarmsim/startup/syscalls.c | 861 +++++++++++++++++++++ 19 files changed, 2059 insertions(+) create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/.cvsignore create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/ChangeLog create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/Makefile.am create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/bsp_specs create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/configure.ac create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/console/.cvsignore create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/include/.cvsignore create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/include/irq.h create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/include/swi.h create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/preinstall.am create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/start/.cvsignore create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/start/start.S create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/startup/.cvsignore create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/startup/bspreset.c create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/startup/bspstart.c create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/startup/linkcmds create mode 100644 c/src/lib/libbsp/arm/gdbarmsim/startup/syscalls.c (limited to 'c') diff --git a/c/src/lib/libbsp/arm/gdbarmsim/.cvsignore b/c/src/lib/libbsp/arm/gdbarmsim/.cvsignore new file mode 100644 index 0000000000..849c802af6 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.cache +config.log +config.status +configure diff --git a/c/src/lib/libbsp/arm/gdbarmsim/ChangeLog b/c/src/lib/libbsp/arm/gdbarmsim/ChangeLog new file mode 100644 index 0000000000..da6fb9ab25 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/ChangeLog @@ -0,0 +1,9 @@ +2009-10-01 Joel Sherrill + + * .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. + diff --git a/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am b/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am new file mode 100644 index 0000000000..e6e4bd8bb4 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/Makefile.am @@ -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 diff --git a/c/src/lib/libbsp/arm/gdbarmsim/bsp_specs b/c/src/lib/libbsp/arm/gdbarmsim/bsp_specs new file mode 100644 index 0000000000..eb3b69e60d --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/bsp_specs @@ -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 } + diff --git a/c/src/lib/libbsp/arm/gdbarmsim/configure.ac b/c/src/lib/libbsp/arm/gdbarmsim/configure.ac new file mode 100644 index 0000000000..cb0c79e3b3 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/configure.ac @@ -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 diff --git a/c/src/lib/libbsp/arm/gdbarmsim/console/.cvsignore b/c/src/lib/libbsp/arm/gdbarmsim/console/.cvsignore new file mode 100644 index 0000000000..849c802af6 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/console/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.cache +config.log +config.status +configure diff --git a/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c b/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c new file mode 100644 index 0000000000..6391358532 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/console/console-io.c @@ -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 +#include +#include +#include + +/* + * 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 + +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; diff --git a/c/src/lib/libbsp/arm/gdbarmsim/include/.cvsignore b/c/src/lib/libbsp/arm/gdbarmsim/include/.cvsignore new file mode 100644 index 0000000000..34cf1342d5 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/include/.cvsignore @@ -0,0 +1,7 @@ +Makefile +Makefile.in +coverhd.h +bspopts.h +bspopts.h.in +stamp-h +stamp-h.in diff --git a/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h b/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h new file mode 100644 index 0000000000..deffeb71b3 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h @@ -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 + +#include +#include +#include +#include + +/* 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 */ + diff --git a/c/src/lib/libbsp/arm/gdbarmsim/include/irq.h b/c/src/lib/libbsp/arm/gdbarmsim/include/irq.h new file mode 100644 index 0000000000..5caf262084 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/include/irq.h @@ -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 +#include +#include + +/** + * @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 */ diff --git a/c/src/lib/libbsp/arm/gdbarmsim/include/swi.h b/c/src/lib/libbsp/arm/gdbarmsim/include/swi.h new file mode 100644 index 0000000000..cf867674fb --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/include/swi.h @@ -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 diff --git a/c/src/lib/libbsp/arm/gdbarmsim/preinstall.am b/c/src/lib/libbsp/arm/gdbarmsim/preinstall.am new file mode 100644 index 0000000000..8675d39723 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/preinstall.am @@ -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 + diff --git a/c/src/lib/libbsp/arm/gdbarmsim/start/.cvsignore b/c/src/lib/libbsp/arm/gdbarmsim/start/.cvsignore new file mode 100644 index 0000000000..849c802af6 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/start/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.cache +config.log +config.status +configure diff --git a/c/src/lib/libbsp/arm/gdbarmsim/start/start.S b/c/src/lib/libbsp/arm/gdbarmsim/start/start.S new file mode 100644 index 0000000000..dc443beb92 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/start/start.S @@ -0,0 +1,403 @@ +/* + * Copied from libgloss 1 Oct 2009. + * Minor modifications to work with RTEMS. + * + * $Id$ + */ + +#include +#include + +/* 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 diff --git a/c/src/lib/libbsp/arm/gdbarmsim/startup/.cvsignore b/c/src/lib/libbsp/arm/gdbarmsim/startup/.cvsignore new file mode 100644 index 0000000000..849c802af6 --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/startup/.cvsignore @@ -0,0 +1,8 @@ +Makefile +Makefile.in +aclocal.m4 +autom4te.cache +config.cache +config.log +config.status +configure diff --git a/c/src/lib/libbsp/arm/gdbarmsim/startup/bspreset.c b/c/src/lib/libbsp/arm/gdbarmsim/startup/bspreset.c new file mode 100644 index 0000000000..a00435142e --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/startup/bspreset.c @@ -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 +#include +#include + +void bsp_reset( void ) +{ + asm ("swi %a0" :: "i" (SWI_Exit)); +} diff --git a/c/src/lib/libbsp/arm/gdbarmsim/startup/bspstart.c b/c/src/lib/libbsp/arm/gdbarmsim/startup/bspstart.c new file mode 100644 index 0000000000..e35945b35e --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/startup/bspstart.c @@ -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 +#include + +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); +} diff --git a/c/src/lib/libbsp/arm/gdbarmsim/startup/linkcmds b/c/src/lib/libbsp/arm/gdbarmsim/startup/linkcmds new file mode 100644 index 0000000000..1a20ec26aa --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/startup/linkcmds @@ -0,0 +1,252 @@ +/* + * Cogent CSB336 Linker script + * + * Copyright (c) 2004 by Cogent Computer Systems + * Written by Jay Monkman + * + * 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 . */ +} + diff --git a/c/src/lib/libbsp/arm/gdbarmsim/startup/syscalls.c b/c/src/lib/libbsp/arm/gdbarmsim/startup/syscalls.c new file mode 100644 index 0000000000..5d4c0de9bb --- /dev/null +++ b/c/src/lib/libbsp/arm/gdbarmsim/startup/syscalls.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 +} -- cgit v1.2.3