forked from Imagelibrary/rtems
Initial revision
This commit is contained in:
37
c/src/lib/libc/README
Normal file
37
c/src/lib/libc/README
Normal 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
40
c/src/lib/libc/__brk.c
Normal 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
84
c/src/lib/libc/__gettod.c
Normal 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
65
c/src/lib/libc/__times.c
Normal 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
41
c/src/lib/libc/internal.h
Normal 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 */
|
||||
47
c/src/lib/libc/libcsupport.h
Normal file
47
c/src/lib/libc/libcsupport.h
Normal 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
280
c/src/lib/libc/malloc.c
Normal 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
292
c/src/lib/libc/newlibc.c
Normal 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
45
c/src/lib/libc/no_libc.c
Normal 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
44
c/src/lib/libc/support.c
Normal 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
77
c/src/lib/libc/syscalls.c
Normal 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
|
||||
7
c/src/lib/libc/unixlibc.c
Normal file
7
c/src/lib/libc/unixlibc.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#if defined(RTEMS_UNIXLIB)
|
||||
|
||||
void libc_init(int reentrant)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user