Initial revision

This commit is contained in:
Joel Sherrill
1995-05-11 17:39:37 +00:00
commit ac7d5ef06a
1683 changed files with 189788 additions and 0 deletions

37
c/src/lib/libc/README Normal file
View File

@@ -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.

40
c/src/lib/libc/__brk.c Normal file
View File

@@ -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 <rtems.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#ifdef RTEMS_NEWLIB
#include <reent.h>
#endif
#include <unistd.h>
/* 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;
}

84
c/src/lib/libc/__gettod.c Normal file
View File

@@ -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 <rtems.h>
#ifdef RTEMS_NEWLIB
#include <sys/reent.h>
#endif
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <assert.h>
/*
* 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

65
c/src/lib/libc/__times.c Normal file
View File

@@ -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 <rtems.h>
#include <sys/times.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <assert.h>
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 );
}

41
c/src/lib/libc/internal.h Normal file
View File

@@ -0,0 +1,41 @@
/* internal.h
*
* This include file contains internal information
* for the RTEMS C library support which is needed across
* files.
*
* 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 __INTERNAL_LIBC_h
#define __INTERNAL_LIBC_h
#ifdef __cplusplus
extern "C" {
#endif
void MY_task_set_note(
rtems_tcb *tcb,
rtems_unsigned32 notepad,
rtems_unsigned32 note
);
rtems_unsigned32 MY_task_get_note(
rtems_tcb *tcb,
rtems_unsigned32 notepad
);
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -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 <sys/types.h>
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 */

280
c/src/lib/libc/malloc.c Normal file
View File

@@ -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 <rtems.h>
#ifdef RTEMS_LIBC
#include <memory.h>
#endif
#include "libcsupport.h"
#ifdef RTEMS_NEWLIB
#include <sys/reent.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
/*
* 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

292
c/src/lib/libc/newlibc.c Normal file
View File

@@ -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 <rtems.h>
#include <libcsupport.h>
#include <stdlib.h> /* for free() */
#include <string.h> /* for memset() */
#include <sys/reent.h> /* 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

45
c/src/lib/libc/no_libc.c Normal file
View File

@@ -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 <rtems.h>
#include "libcsupport.h"
#include "internal.h"
#include <stdlib.h> /* for free() */
void
libc_init(int reentrant)
{
}
void libc_suspend_main(void)
{
}
void libc_global_exit(rtems_unsigned32 code)
{
}
void _exit(int status)
{
}
#endif

44
c/src/lib/libc/support.c Normal file
View File

@@ -0,0 +1,44 @@
/*
* Routines to Access Internal RTEMS Resources
*
* 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 <rtems/system.h>
#include <rtems/thread.h>
void MY_task_set_note(
Thread_Control *the_thread,
unsigned32 notepad,
unsigned32 note
)
{
the_thread->Notepads[ notepad ] = note;
}
unsigned32 MY_task_get_note(
Thread_Control *the_thread,
unsigned32 notepad
)
{
return the_thread->Notepads[ notepad ];
}
void *MY_CPU_Context_FP_start(
void *base,
unsigned32 offset
)
{
return _CPU_Context_Fp_start( base, offset );
}

77
c/src/lib/libc/syscalls.c Normal file
View File

@@ -0,0 +1,77 @@
#if !defined(RTEMS_UNIX)
/*
* RTEMS Fake System Calls
*
* This file contains "fake" versions of the system call routines
* which are reference by many libc implementations. Once a routine
* has been implemented in terms of RTEMS services, it should be
* taken out of this file.
*
* 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 <sys/types.h>
#include <sys/stat.h>
int
__fstat(int _fd, struct stat* _sbuf)
{
return -1;
}
int
__isatty(int _fd)
{
return 1;
}
int
__close(int _fd)
{
/* return value usually ignored anyhow */
return 0;
}
int
__open(const char *filename)
{
/* always fail */
return -1;
}
int
__lseek(int _fd, off_t offset, int whence)
{
/* nothing is ever seekable */
return -1;
}
int stat( const char *path, struct stat *buf )
{
/* always fail */
return -1;
}
int link( const char *existing, const char *new )
{
/* always fail */
return -1;
}
int unlink( const char *path )
{
/* always fail */
return -1;
}
#endif

View File

@@ -0,0 +1,7 @@
#if defined(RTEMS_UNIXLIB)
void libc_init(int reentrant)
{
}
#endif