166 lines
5.3 KiB
C
166 lines
5.3 KiB
C
|
/* EPIPHANY implementation of _sbrk ()
|
||
|
|
||
|
Copyright (c) 2011, Adapteva, Inc.
|
||
|
All rights reserved.
|
||
|
|
||
|
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com> for Adapteva Inc
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions are met:
|
||
|
* Redistributions of source code must retain the above copyright notice,
|
||
|
this list of conditions and the following disclaimer.
|
||
|
* Redistributions in binary form must reproduce the above copyright
|
||
|
notice, this list of conditions and the following disclaimer in the
|
||
|
documentation and/or other materials provided with the distribution.
|
||
|
* Neither the name of Adapteva nor the names of its contributors may be
|
||
|
used to endorse or promote products derived from this software without
|
||
|
specific prior written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
POSSIBILITY OF SUCH DAMAGE. */
|
||
|
/* ------------------------------------------------------------------------- */
|
||
|
/* This implementation is suitable for use with the Verilator simulation of
|
||
|
the EPIPHANY.
|
||
|
|
||
|
Commenting suitable for processing by Doxygen is provided throughout. */
|
||
|
/* ------------------------------------------------------------------------- */
|
||
|
#include <sys/types.h>
|
||
|
#include <errno.h>
|
||
|
#include <stddef.h>
|
||
|
|
||
|
/* ------------------------------------------------------------------------- */
|
||
|
/*!Increase program data space
|
||
|
|
||
|
This is a minimal implementation. Assuming the heap is growing upwards
|
||
|
from __heap_start towards __heap_end.
|
||
|
See linker file for definition.
|
||
|
|
||
|
@param[in] incr The number of bytes to increment the stack by.
|
||
|
|
||
|
@return A pointer to the start of the new block of memory */
|
||
|
/* ------------------------------------------------------------------------- */
|
||
|
void *
|
||
|
_sbrk (int incr)
|
||
|
{
|
||
|
extern char __heap_start;//set by linker
|
||
|
extern char __heap_end;//set by linker
|
||
|
|
||
|
static char *heap_end; /* Previous end of heap or 0 if none */
|
||
|
char *prev_heap_end;
|
||
|
|
||
|
if (0 == heap_end) {
|
||
|
heap_end = &__heap_start; /* Initialize first time round */
|
||
|
}
|
||
|
|
||
|
prev_heap_end = heap_end;
|
||
|
heap_end += incr;
|
||
|
//check
|
||
|
if( heap_end < (&__heap_end)) {
|
||
|
|
||
|
} else {
|
||
|
errno = ENOMEM;
|
||
|
return (char*)-1;
|
||
|
}
|
||
|
return (void *) prev_heap_end;
|
||
|
|
||
|
} /* _sbrk () */
|
||
|
|
||
|
|
||
|
|
||
|
///* sbrk support */
|
||
|
//
|
||
|
///* The current plan is to have one sbrk handler for all cpus.
|
||
|
// Hence use `asm' for each global variable here to avoid the cpu prefix.
|
||
|
// We can't intrude on the user's namespace (another reason to use asm). */
|
||
|
//
|
||
|
//#include <sys/types.h>
|
||
|
///*#include <sys/syscall.h>*/
|
||
|
//#include <errno.h>
|
||
|
//#include <stddef.h>
|
||
|
//
|
||
|
///* These variables are publicly accessible for debugging purposes.
|
||
|
// The user is also free to set sbrk_size to something different.
|
||
|
// See mem-layout.c. */
|
||
|
//
|
||
|
//extern int sbrk_size asm ("sbrk_size");
|
||
|
//
|
||
|
//caddr_t sbrk_start asm ("sbrk_start");
|
||
|
//caddr_t sbrk_loc asm ("sbrk_loc");
|
||
|
//extern char end; /* Defined by linker. */
|
||
|
//
|
||
|
///*caddr_t _sbrk_r (struct _reent *, size_t) asm ("__sbrk_r");*/
|
||
|
//
|
||
|
//
|
||
|
///* This symbol can be defined with the --defsym linker option. */
|
||
|
//extern char __heap_end __attribute__((weak));
|
||
|
//
|
||
|
//
|
||
|
///* FIXME: We need a semaphore here. */
|
||
|
//
|
||
|
//caddr_t
|
||
|
//_sbrk_r (struct _reent *r, size_t nbytes)
|
||
|
//{
|
||
|
// extern char end; /* Defined by linker. */
|
||
|
// static char *heap_end; /* Previous end of heap or 0 if none */
|
||
|
// char *prev_heap_end;
|
||
|
// register char* stack asm("sp");
|
||
|
//
|
||
|
// if (0 == heap_end)
|
||
|
// {
|
||
|
// heap_end = &end; /* Initialize first time round */
|
||
|
// }
|
||
|
//
|
||
|
// prev_heap_end = heap_end;
|
||
|
//
|
||
|
// if (stack < (prev_heap_end+nbytes)) {
|
||
|
// /* heap would overlap the current stack depth.
|
||
|
// * Future: use sbrk() system call to make simulator grow memory beyond
|
||
|
// * the stack and allocate that
|
||
|
// */
|
||
|
// errno = ENOMEM;
|
||
|
// return (char*)-1;
|
||
|
// }
|
||
|
//
|
||
|
// heap_end += nbytes;
|
||
|
//
|
||
|
// return (caddr_t) prev_heap_end;
|
||
|
//
|
||
|
//} /* _sbrk () */
|
||
|
|
||
|
|
||
|
//caddr_t
|
||
|
//_sbrk_r (struct _reent *r, size_t nbytes)
|
||
|
//{
|
||
|
// caddr_t result;
|
||
|
//
|
||
|
// void *heap_end;
|
||
|
//
|
||
|
// heap_end = &__heap_end;
|
||
|
// if (!heap_end)
|
||
|
// heap_end = sbrk_start + sbrk_size;
|
||
|
// if (
|
||
|
// /* Ensure we don't underflow. */
|
||
|
// sbrk_loc + nbytes < sbrk_start
|
||
|
// /* Ensure we don't overflow. */
|
||
|
// || sbrk_loc + nbytes > (caddr_t)heap_end)
|
||
|
// {
|
||
|
// errno = ENOMEM;
|
||
|
// return ((caddr_t) -1);
|
||
|
// }
|
||
|
//
|
||
|
// if (0 == sbrk_loc)
|
||
|
// sbrk_loc = &end; /* Initialize first time round */
|
||
|
// result = sbrk_loc;
|
||
|
// sbrk_loc += nbytes;
|
||
|
// return result;
|
||
|
//}
|