summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/shared/startup/sbrk.c
blob: 3a8b5664f8ec910b1a1d8e96e84f01f84cedf004 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* $Id$ */

/*
 *  sbrk.c
 *
 *  Author: Till Straumann <strauman@slac.stanford.edu>, 2002
 *
 *  Hack around the 32bit powerpc 32M problem:
 *
 *  GCC by default uses relative branches which can not jump
 *  farther than 32M. Hence all program text is confined to
 *  a single 32M segment.
 *  This hack gives the RTEMS malloc region all memory below
 *  32M at startup. Only when this region is exhausted will sbrk
 *  add more memory. Loading modules may fail at that point, hence
 *  the user is expected to load all modules at startup _prior_
 *  to malloc()ing lots of memory...
 *
 *  NOTE: it would probably be better to have a separate region
 *        for module code.
 */

#include <rtems.h>

#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>

static uint32_t         remaining_start=0;
static uint32_t         remaining_size=0;

#define LIMIT_32M  0x02000000

uint32_t        
_bsp_sbrk_init(uint32_t         heap_start, uint32_t         *heap_size_p)
{
  uint32_t         rval=0;

  remaining_start =  heap_start;
  remaining_size  =*  heap_size_p;
  if (remaining_start < LIMIT_32M &&
      remaining_start + remaining_size > LIMIT_32M) {
    /* clip at LIMIT_32M */
    rval = remaining_start + remaining_size - LIMIT_32M;
    *heap_size_p = LIMIT_32M - remaining_start;
  }
  return rval;
}

void * sbrk(ptrdiff_t incr)
{
  void *rval=(void*)-1;

  if (incr <= remaining_size) {
    remaining_size-=incr;
    rval = (void*)remaining_start;
    remaining_start += incr;
  } else {
    errno = ENOMEM;
  }
  return rval;
}