From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- cpukit/libcsupport/include/clockdrv.h | 58 +++++ cpukit/libcsupport/include/console.h | 40 ++++ cpukit/libcsupport/include/iosupp.h | 44 ++++ cpukit/libcsupport/include/rtems/libcsupport.h | 47 ++++ cpukit/libcsupport/include/spurious.h | 38 ++++ cpukit/libcsupport/include/timerdrv.h | 40 ++++ cpukit/libcsupport/include/vmeintr.h | 58 +++++ cpukit/libcsupport/src/README | 37 ++++ cpukit/libcsupport/src/__brk.c | 40 ++++ cpukit/libcsupport/src/__gettod.c | 84 +++++++ cpukit/libcsupport/src/__times.c | 65 ++++++ cpukit/libcsupport/src/malloc.c | 280 ++++++++++++++++++++++++ cpukit/libcsupport/src/newlibc.c | 292 +++++++++++++++++++++++++ cpukit/libcsupport/src/no_libc.c | 45 ++++ cpukit/libcsupport/src/unixlibc.c | 7 + 15 files changed, 1175 insertions(+) create mode 100644 cpukit/libcsupport/include/clockdrv.h create mode 100644 cpukit/libcsupport/include/console.h create mode 100644 cpukit/libcsupport/include/iosupp.h create mode 100644 cpukit/libcsupport/include/rtems/libcsupport.h create mode 100644 cpukit/libcsupport/include/spurious.h create mode 100644 cpukit/libcsupport/include/timerdrv.h create mode 100644 cpukit/libcsupport/include/vmeintr.h create mode 100644 cpukit/libcsupport/src/README create mode 100644 cpukit/libcsupport/src/__brk.c create mode 100644 cpukit/libcsupport/src/__gettod.c create mode 100644 cpukit/libcsupport/src/__times.c create mode 100644 cpukit/libcsupport/src/malloc.c create mode 100644 cpukit/libcsupport/src/newlibc.c create mode 100644 cpukit/libcsupport/src/no_libc.c create mode 100644 cpukit/libcsupport/src/unixlibc.c (limited to 'cpukit/libcsupport') diff --git a/cpukit/libcsupport/include/clockdrv.h b/cpukit/libcsupport/include/clockdrv.h new file mode 100644 index 0000000000..aad9bd6d3b --- /dev/null +++ b/cpukit/libcsupport/include/clockdrv.h @@ -0,0 +1,58 @@ +/* clock.h + * + * This file describes the Clock Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __CLOCK_DRIVER_h +#define __CLOCK_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* variables */ + +extern volatile rtems_unsigned32 Clock_driver_ticks; + +/* functions */ + +rtems_task Exit_task(); +void exit_task_init(); + +void Install_clock( rtems_isr_entry ); +void ReInstall_clock( rtems_isr_entry ); +void Clock_exit(); + +rtems_isr Clock_isr( + rtems_vector_number +); + +/* driver entries */ + +#define CLOCK_DRIVER_TABLE_ENTRY \ + { Clock_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Clock_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/console.h b/cpukit/libcsupport/include/console.h new file mode 100644 index 0000000000..d102c6a1b1 --- /dev/null +++ b/cpukit/libcsupport/include/console.h @@ -0,0 +1,40 @@ +/* console.h + * + * This file describes the Console Device Driver for all boards. + * This driver provides support for the standard C Library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef _CONSOLE_DRIVER_h +#define _CONSOLE_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONSOLE_DRIVER_TABLE_ENTRY \ + { console_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver console_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/iosupp.h b/cpukit/libcsupport/include/iosupp.h new file mode 100644 index 0000000000..5f4a83b8ca --- /dev/null +++ b/cpukit/libcsupport/include/iosupp.h @@ -0,0 +1,44 @@ +/* iosupp.h + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __IOSUPP_h +#define __IOSUPP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* character constants */ + +#define BS 0x08 /* backspace */ +#define LF 0x0a /* line feed */ +#define CR 0x0d /* carriage return */ +#define XON 0x11 /* control-Q */ +#define XOFF 0x13 /* control-S */ + +/* structures */ + +#ifdef IOSUPP_INIT +#define IOSUPP_EXTERN +#else +#undef IOSUPP_EXTERN +#define IOSUPP_EXTERN extern +#endif + +/* functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h new file mode 100644 index 0000000000..2b199707f8 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -0,0 +1,47 @@ +/* libcsupport.h + * + * This include file contains the information regarding the + * RTEMS specific support for the standard C library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __LIBC_SUPPORT_h +#define __LIBC_SUPPORT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +); + +extern void libc_init(int reentrant); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/spurious.h b/cpukit/libcsupport/include/spurious.h new file mode 100644 index 0000000000..428e826164 --- /dev/null +++ b/cpukit/libcsupport/include/spurious.h @@ -0,0 +1,38 @@ +/* spurious.h + * + * This file describes the Spurious Interrupt Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SPURIOUS_h +#define __SPURIOUS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPURIOUS_DRIVER_TABLE_ENTRY \ + { Spurious_Initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Spurious_Initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/timerdrv.h b/cpukit/libcsupport/include/timerdrv.h new file mode 100644 index 0000000000..d091b62410 --- /dev/null +++ b/cpukit/libcsupport/include/timerdrv.h @@ -0,0 +1,40 @@ +/* timerdrv.h + * + * This file describes the Timer Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIMER_DRIVER_h +#define __TIMER_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* functions */ + +void Timer_initialize( void ); + +rtems_unsigned32 Read_timer( void ); + +rtems_status_code Empty_function( void ); + +void Set_find_average_overhead( + rtems_boolean find_flag +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/vmeintr.h b/cpukit/libcsupport/include/vmeintr.h new file mode 100644 index 0000000000..6148114ce8 --- /dev/null +++ b/cpukit/libcsupport/include/vmeintr.h @@ -0,0 +1,58 @@ +/* + * vmeintr.h + * + * This file is the specification for the VMEbus interface library + * which should be provided by all BSPs for VMEbus Single Board + * Computers but currently only a few do so. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __VME_INTERRUPT_h +#define __VME_INTERRUPT_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the mask which is used to determine which + * interrupt levels are affected by a call to this package. + * The LSB corresponds to VME interrupt 0 and the MSB + * to VME interrupt 7. + * + */ + +typedef rtems_unsigned8 VME_interrupt_Mask; + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Disable ( + VME_interrupt_Mask mask /* IN */ +); + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Enable ( + VME_interrupt_Mask mask /* IN */ +); + +#ifdef __cplusplus +} +#endif + +#endif /* end of include file */ diff --git a/cpukit/libcsupport/src/README b/cpukit/libcsupport/src/README new file mode 100644 index 0000000000..ee7a90501e --- /dev/null +++ b/cpukit/libcsupport/src/README @@ -0,0 +1,37 @@ +-- +-- $Id$ +-- + +Overview of newlib support (newlib is from CYGNUS) + Each task can have its own libc state including: + open stdio files + strtok + multi precision arithmetic state + etc. + + This is implemented by a reentrancy data structure for each task. + + When a task is "started" (in RTEMS sense) the reentrancy structure + is allocated. Its address is stored in notepad[NOTEPAD_LAST]. + + When task is switched to, the value of global variable _impure_ptr + is changed to the value of the new tasks reentrancy structure. + + When a task is deleted + atexit() processing (for that task) happens + task's stdio buffers are flushed + + When exit(3) is called + calling task's atexit processing done + global libc state atexit processing done + (this will include any atexit routines installed by drivers) + executive is shutdown + causes a context switch back to bsp land + + +NOTE: + libc extension are installed by bsp_libc_init() + iff we are using clock interrupts. + This hack is necessary to allow the tmtests to avoid + timing the extensions. + diff --git a/cpukit/libcsupport/src/__brk.c b/cpukit/libcsupport/src/__brk.c new file mode 100644 index 0000000000..6fb15342fe --- /dev/null +++ b/cpukit/libcsupport/src/__brk.c @@ -0,0 +1,40 @@ +/* + * RTEMS "Broken" __brk/__sbrk Implementation + * + * NOTE: sbrk is BSP provided. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#ifdef RTEMS_NEWLIB +#include +#endif +#include + +/* we use RTEMS for memory management. We don't need sbrk */ + +void * __sbrk(int incr) +{ + errno = EINVAL; + return (void *)0; +} + +int __brk( const void *endds ) +{ + errno = EINVAL; + return -1; +} diff --git a/cpukit/libcsupport/src/__gettod.c b/cpukit/libcsupport/src/__gettod.c new file mode 100644 index 0000000000..a1ab9776c8 --- /dev/null +++ b/cpukit/libcsupport/src/__gettod.c @@ -0,0 +1,84 @@ +#if !defined(RTEMS_UNIX) +/* + * RTEMS gettimeofday Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#ifdef RTEMS_NEWLIB +#include +#endif +#include +#include +#include +#include + +/* + * NOTE: The solaris gettimeofday does not have a second parameter. + */ + +int gettimeofday( + struct timeval *tp, + struct timezone *tzp +) +{ + rtems_status_code status; + rtems_clock_time_value time; + + if ( !tp || !tzp ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( RTEMS_CLOCK_GET_TIME_VALUE, &time ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + tp->tv_sec = time.seconds; + tp->tv_usec = time.microseconds; + +#if 0 + tzp->minuteswest = timezone / 60; /* from seconds to minutes */ + tzp->dsttime = daylight; +#endif + + /* + * newlib does not have timezone and daylight savings time + * yet. When it does this needs to be fixed. + */ + + tzp->tz_minuteswest = 0; /* at UTC */ + tzp->tz_dsttime = 0; /* no daylight savings */ + return 0; +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#if 0 +int _gettimeofday_r( + struct _reent *ignored_reentrancy_stuff, + struct timeval *tp, + struct timezone *tzp +) +{ + return gettimeofday( tp, tzp ); +} +#endif + +#endif diff --git a/cpukit/libcsupport/src/__times.c b/cpukit/libcsupport/src/__times.c new file mode 100644 index 0000000000..12fd9241fe --- /dev/null +++ b/cpukit/libcsupport/src/__times.c @@ -0,0 +1,65 @@ +/* + * RTEMS _times Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include + +clock_t _times( + struct tms *ptms +) +{ + rtems_status_code status; + rtems_interval ticks_since_boot; + + if ( !ptms ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + &ticks_since_boot + ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + /* + * RTEMS has no notion of system versus user time and does + * not (as of 3.2.0) keep track of CPU usage on a per task basis. + */ + + ptms->tms_utime = ticks_since_boot; + ptms->tms_stime = 0; + ptms->tms_cutime = 0; + ptms->tms_cstime = 0; + + return 0; +} + +clock_t times( + struct tms *ptms +) +{ + return _times( ptms ); +} + diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c new file mode 100644 index 0000000000..7d0ba04143 --- /dev/null +++ b/cpukit/libcsupport/src/malloc.c @@ -0,0 +1,280 @@ +/* + * RTEMS Malloc Family Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#ifdef RTEMS_LIBC +#include +#endif +#include "libcsupport.h" +#ifdef RTEMS_NEWLIB +#include +#endif + +#include +#include +#include +#include +#include +#include + +/* + * XXX: Do we really need to duplicate these? It appears that they + * only cause typing problems. + */ + +#if 0 +void *malloc(size_t); +void *calloc(size_t, size_t); +void *realloc(void *, size_t); +void free(void *); +void *sbrk(size_t); +#endif + +rtems_id RTEMS_Malloc_Heap; +size_t RTEMS_Malloc_Sbrk_amount; + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +) +{ + rtems_status_code status; + void *starting_address; + rtems_unsigned32 u32_address; + + /* + * If the starting address is 0 then we are to attempt to + * get length worth of memory using sbrk. Make sure we + * align the address that we get back. + */ + + starting_address = start; + + if (!starting_address) { + u32_address = (unsigned int)sbrk(length); + + if (u32_address == -1) { + rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); + /* DOES NOT RETURN!!! */ + } + + if (u32_address & (CPU_ALIGNMENT-1)) { + u32_address = (u32_address + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + /* XXX: if we do any alignment .. then length should be shortened */ + } + + starting_address = (void *)u32_address; + } + + /* + * Unfortunately we cannot use assert if this fails because if this + * has failed we do not have a heap and if we do not have a heap + * STDIO cannot work because there will be no buffers. + */ + + status = rtems_region_create( + rtems_build_name( 'H', 'E', 'A', 'P' ), + starting_address, + length, + 8, /* XXX : use CPU dependent RTEMS constant */ + RTEMS_DEFAULT_ATTRIBUTES, + &RTEMS_Malloc_Heap + ); + if ( status != RTEMS_SUCCESSFUL ) + rtems_fatal_error_occurred( status ); +} + +void *malloc( + size_t size +) +{ + void *return_this; + void *starting_address; + rtems_unsigned32 the_size; + rtems_unsigned32 sbrk_amount; + rtems_status_code status; + + if ( !size ) + return (void *) 0; + + /* + * Try to give a segment in the current region if there is not + * enough space then try to grow the region using rtems_region_extend(). + * If this fails then return a NULL pointer. + */ + + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + + if ( status != RTEMS_SUCCESSFUL ) { + /* + * Round to the "requested sbrk amount" so hopefully we won't have + * to grow again for a while. This effectively does sbrk() calls + * in "page" amounts. + */ + + sbrk_amount = RTEMS_Malloc_Sbrk_amount; + + if ( sbrk_amount == 0 ) + return (void *) 0; + + the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); + + if (((rtems_unsigned32)starting_address = sbrk(the_size)) == -1) + return (void *) 0; + + /* + fprintf(stderr, "Extended the C heap starting at 0x%x for %d bytes\n", + (unsigned32)starting_address, the_size); + */ + + status = rtems_region_extend( + RTEMS_Malloc_Heap, + starting_address, + the_size + ); + if ( status != RTEMS_SUCCESSFUL ) { + sbrk(-the_size); + return(FALSE); + errno = ENOMEM; + return (void *) 0; + } + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = ENOMEM; + return (void *) 0; + } + } + + return return_this; +} + +void *calloc( + size_t nelem, + size_t elsize +) +{ + register char *cptr; + int length; + + length = nelem * elsize; + cptr = malloc( length ); + if ( cptr ) + memset( cptr, '\0', length ); + + return cptr; +} + +void *realloc( + void *ptr, + size_t size +) +{ + rtems_unsigned32 old_size; + rtems_status_code status; + char *new_area; + + if ( !ptr ) + return malloc( size ); + + if ( !size ) { + free( ptr ); + return (void *) 0; + } + + status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &old_size ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + return (void *) 0; + } + + new_area = malloc( size ); + if ( !new_area ) { + free( ptr ); + return (void *) 0; + } + + memcpy( new_area, ptr, (size < old_size) ? size : old_size ); + free( ptr ); + + return new_area; + +} + +void free( + void *ptr +) +{ + rtems_status_code status; + + if ( !ptr ) + return; + + status = rtems_region_return_segment( RTEMS_Malloc_Heap, ptr ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + assert( 0 ); + } +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#ifdef RTEMS_NEWLIB +void *malloc_r( + struct _reent *ignored, + size_t size +) +{ + return malloc( size ); +} + +void *calloc_r( + size_t nelem, + size_t elsize +) +{ + return calloc( nelem, elsize ); +} + +void *realloc_r( + void *ptr, + size_t size +) +{ + return realloc_r( ptr, size ); +} + +void free_r( + void *ptr +) +{ + free( ptr ); +} +#endif + diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c new file mode 100644 index 0000000000..3c5e58b67c --- /dev/null +++ b/cpukit/libcsupport/src/newlibc.c @@ -0,0 +1,292 @@ +/* + * @(#)newlibc.c 1.8 - 95/04/25 + * + */ + +#if defined(RTEMS_NEWLIB) + +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/12/7 + * Revision: $Revision$ + * Last Mod: $Date$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * Description: + * Implementation of hooks for the CYGNUS newlib libc + * These hooks set things up so that: + * '_REENT' is switched at task switch time. + * + * + * TODO: + * + * NOTE: + * + * $Id$ + * + */ + +#include +#include +#include /* for free() */ +#include /* for memset() */ + +#include /* for extern of _REENT (aka _impure_ptr) */ + +#include "internal.h" + +#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST + + +int libc_reentrant; /* do we think we are reentrant? */ +struct _reent libc_global_reent = _REENT_INIT(libc_global_reent);; + +/* + * CYGNUS newlib routine that does atexit() processing and flushes + * stdio streams + * undocumented + */ + +extern void _wrapup_reent(struct _reent *); +extern void _reclaim_reent(struct _reent *); + +void +libc_wrapup(void) +{ + _wrapup_reent(0); + if (_REENT != &libc_global_reent) + { + _wrapup_reent(&libc_global_reent); +#if 0 + /* don't reclaim this one, just in case we do printfs */ + /* on our way out to ROM */ + _reclaim_reent(&libc_global_reent); +#endif + _REENT = &libc_global_reent; + } +} + + +rtems_extension +libc_create_hook(rtems_tcb *current_task, + rtems_tcb *creating_task) +{ + MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); +} + +/* + * Called for all user TASKS (system tasks are SYSI and IDLE) + */ + +rtems_extension +libc_start_hook(rtems_tcb *current_task, + rtems_tcb *starting_task) +{ + struct _reent *ptr; + + /* NOTE: our malloc is reentrant without a reent ptr since + * it is based on region manager + */ + + ptr = (struct _reent *) malloc(sizeof(struct _reent)); + + /* GCC extension: structure constants */ + *ptr = (struct _reent) _REENT_INIT((*ptr)); + + MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); +} + +rtems_extension +libc_switch_hook(rtems_tcb *current_task, + rtems_tcb *heir_task) +{ + rtems_unsigned32 impure_value; + + /* XXX We can't use rtems_task_set_note() here since SYSI task has a + * tid of 0, which is treated specially (optimized, actually) + * by rtems_task_set_note + */ + + impure_value = (rtems_unsigned32) _REENT; + MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); + + _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); + +} + +/* + * Function: libc_delete_hook + * Created: 94/12/10 + * + * Description: + * Called when a task is deleted. + * Must restore the new lib reentrancy state for the new current + * task. + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ +rtems_extension +libc_delete_hook(rtems_tcb *current_task, + rtems_tcb *deleted_task) +{ + struct _reent *ptr; + + /* + * The reentrancy structure was allocated by newlib using malloc() + */ + + if (current_task == deleted_task) + { + ptr = _REENT; + } + else + { + ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); + } + + if (ptr) + { + _wrapup_reent(ptr); + _reclaim_reent(ptr); + } + + MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); + + /* + * Require the switch back to another task to install its own + */ + + if (current_task == deleted_task) + { + _REENT = 0; + } +} + +/* + * Function: libc_init + * Created: 94/12/10 + * + * Description: + * Init libc for CYGNUS newlib + * Set up _REENT to use our global libc_global_reent. + * (newlib provides a global of its own, but we prefer our + * own name for it) + * + * If reentrancy is desired (which it should be), then + * we install the task extension hooks to maintain the + * newlib reentrancy global variable _REENT on task + * create, delete, switch, exit, etc. + * + * Parameters: + * reentrant non-zero if reentrant library desired. + * + * Returns: + * + * Side Effects: + * installs libc extensions if reentrant. + * + * Notes: + * + * + * Deficiencies/ToDo: + * + */ + +void +libc_init(int reentrant) +{ + rtems_extensions_table libc_extension; + rtems_id extension_id; + rtems_status_code rc; + + _REENT = &libc_global_reent; + + if (reentrant) + { + memset(&libc_extension, 0, sizeof(libc_extension)); + + libc_extension.rtems_task_create = libc_create_hook; + libc_extension.rtems_task_start = libc_start_hook; + libc_extension.task_switch = libc_switch_hook; + libc_extension.rtems_task_delete = libc_delete_hook; + + rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), + &libc_extension, &extension_id); + if (rc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(rc); + + libc_reentrant = reentrant; + } +} + + +void +exit(int status) +{ + libc_wrapup(); + rtems_shutdown_executive(status); +} + + +/* + * Function: _exit + * Created: 94/12/10 + * + * Description: + * Called from exit() after it does atexit() processing and stdio fflush's + * + * called from bottom of exit() to really delete the task. + * If we are using reentrant libc, then let the delete extension + * do all the work, otherwise if a shutdown is in progress, + * then just do it. + * + * Parameters: + * exit status + * + * Returns: + * does not return + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +#ifndef RTEMS_UNIX +void _exit(int status) +{ + rtems_shutdown_executive(status); +} +#endif + +#endif diff --git a/cpukit/libcsupport/src/no_libc.c b/cpukit/libcsupport/src/no_libc.c new file mode 100644 index 0000000000..43a91eb30e --- /dev/null +++ b/cpukit/libcsupport/src/no_libc.c @@ -0,0 +1,45 @@ +#if !defined(RTEMS_LIBC) && !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX) + +/* no_libc.h + * + * This file contains stubs for the reentrancy hooks when + * an unknown C library is used. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include + +#include "libcsupport.h" +#include "internal.h" + +#include /* for free() */ + +void +libc_init(int reentrant) +{ +} + +void libc_suspend_main(void) +{ +} + + +void libc_global_exit(rtems_unsigned32 code) +{ +} + +void _exit(int status) +{ +} + +#endif diff --git a/cpukit/libcsupport/src/unixlibc.c b/cpukit/libcsupport/src/unixlibc.c new file mode 100644 index 0000000000..74b4eea360 --- /dev/null +++ b/cpukit/libcsupport/src/unixlibc.c @@ -0,0 +1,7 @@ +#if defined(RTEMS_UNIXLIB) + +void libc_init(int reentrant) +{ +} + +#endif -- cgit v1.2.3