source: rtems/bsps/powerpc/shared/start/sbrk.c @ eea21eac

5
Last change on this file since eea21eac was eea21eac, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 13, 2019 at 5:18:36 AM

bsps: Rework work area initialization

The work area initialization was done by the BSP through
bsp_work_area_initialize(). This approach predated the system
initialization through the system initialization linker set. The
workspace and C program heap were unconditionally initialized. The aim
is to support RTEMS application configurations which do not need the
workspace and C program heap. In these configurations, the workspace
and C prgram heap should not get initialized.

Change all bsp_work_area_initialize() to implement _Memory_Get()
instead. Move the dirty memory, sbrk(), per-CPU data, workspace, and
malloc() heap initialization into separate system initialization steps.
This makes it also easier to test the individual initialization steps.

This change adds a dependency to _Heap_Extend() to all BSPs. This
dependency will be removed in a follow up change.

Update #3838.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 *  sbrk.c
3 *
4 * Authorship
5 * ----------
6 * This software was created by
7 *     Till Straumann <strauman@slac.stanford.edu>, 2002,
8 *        Stanford Linear Accelerator Center, Stanford University.
9 *
10 * Acknowledgement of sponsorship
11 * ------------------------------
12 * This software was produced by
13 *     the Stanford Linear Accelerator Center, Stanford University,
14 *        under Contract DE-AC03-76SFO0515 with the Department of Energy.
15 *
16 * Government disclaimer of liability
17 * ----------------------------------
18 * Neither the United States nor the United States Department of Energy,
19 * nor any of their employees, makes any warranty, express or implied, or
20 * assumes any legal liability or responsibility for the accuracy,
21 * completeness, or usefulness of any data, apparatus, product, or process
22 * disclosed, or represents that its use would not infringe privately owned
23 * rights.
24 *
25 * Stanford disclaimer of liability
26 * --------------------------------
27 * Stanford University makes no representations or warranties, express or
28 * implied, nor assumes any liability for the use of this software.
29 *
30 * Stanford disclaimer of copyright
31 * --------------------------------
32 * Stanford University, owner of the copyright, hereby disclaims its
33 * copyright and all other rights in this software.  Hence, anyone may
34 * freely use it for any purpose without restriction.
35 *
36 * Maintenance of notices
37 * ----------------------
38 * In the interest of clarity regarding the origin and status of this
39 * SLAC software, this and all the preceding Stanford University notices
40 * are to remain affixed to any copy or derivative of this software made
41 * or distributed by the recipient and are to be affixed to any copy of
42 * software made or distributed by the recipient that contains a copy or
43 * derivative of this software.
44 *
45 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
46 */
47
48/*
49 *  Hack around the 32bit powerpc 32M problem:
50 *
51 *  GCC by default uses relative branches which can not jump
52 *  farther than 32M. Hence all program text is confined to
53 *  a single 32M segment.
54 *  This hack gives the RTEMS malloc region all memory below
55 *  32M at startup. Only when this region is exhausted will sbrk
56 *  add more memory. Loading modules may fail at that point, hence
57 *  the user is expected to load all modules at startup _prior_
58 *  to malloc()ing lots of memory...
59 *
60 *  NOTE: it would probably be better to have a separate region
61 *        for module code.
62 */
63
64#include <errno.h>
65#include <unistd.h>
66
67#include <bsp.h>
68#include <bsp/bootcard.h>
69
70#include <rtems/sysinit.h>
71
72#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
73
74#define INVALID_REMAINING_START ((uintptr_t) -1)
75
76static uintptr_t remaining_start = INVALID_REMAINING_START;
77static uintptr_t remaining_size = 0;
78
79/* App. may provide a value by defining the BSP_sbrk_policy
80 * variable.
81 *
82 *  (-1) -> give all memory to the heap at initialization time
83 *  > 0  -> value used as sbrk amount; initially give 32M
84 *    0  -> limit memory effectively to 32M.
85 *
86 */
87extern uintptr_t        BSP_sbrk_policy[] __attribute__((weak));
88
89#define LIMIT_32M  0x02000000
90
91/**
92 * @brief Gives the BSP a chance to reduce the work area size with sbrk()
93 * adding more later.
94 *
95 * bsp_sbrk_init() may reduce the work area size passed in. The routine
96 * returns the 'sbrk_amount' to be used when extending the heap.  Note that
97 * the return value may be zero.
98 *
99 * In case the @a mem area size is altered, then the remaining size of the
100 * @a mem area must be greater than or equal to @a min_size.
101 */
102static ptrdiff_t bsp_sbrk_init(const Memory_Information *mem, uintptr_t min_size)
103{
104  uintptr_t         rval = 0;
105  uintptr_t         policy;
106  uintptr_t         remaining_end;
107  Memory_Area      *area;
108
109  area = &mem->areas[ 0 ];
110  remaining_start = (uintptr_t) _Memory_Get_free_begin(area);
111  remaining_size  = _Memory_Get_free_size(area);
112  remaining_end   = (uintptr_t) _Memory_Get_end(area);
113
114  if (remaining_start < LIMIT_32M &&
115      remaining_end > LIMIT_32M &&
116      min_size <= LIMIT_32M - remaining_start) {
117    /* clip at LIMIT_32M */
118    rval = remaining_end - LIMIT_32M;
119    _Memory_Set_end(area, (void *) (LIMIT_32M - remaining_start));
120    remaining_start = LIMIT_32M;
121    remaining_size  = rval;
122  }
123
124  policy = (0 == BSP_sbrk_policy[0] ? (uintptr_t)(-1) : BSP_sbrk_policy[0]);
125  switch ( policy ) {
126      case (uintptr_t)(-1):
127        _Memory_Set_end(area, (const char *) _Memory_Get_end(area) + rval);
128        remaining_start = (uintptr_t) _Memory_Get_end(area);
129        remaining_size  = 0;
130      break;
131
132      case 0:
133        remaining_size = 0;
134      break;
135
136      default:
137        if ( rval > policy )
138          rval = policy;
139      break;
140  }
141
142  return (ptrdiff_t) (rval <= PTRDIFF_MAX ? rval : rval / 2);
143}
144
145void *sbrk(ptrdiff_t incr)
146{
147  void *rval=(void*)-1;
148
149  if ( remaining_start != INVALID_REMAINING_START && incr <= remaining_size) {
150    remaining_size-=incr;
151    rval = (void *) remaining_start;
152    remaining_start += incr;
153  } else {
154    errno = ENOMEM;
155  }
156  #ifdef DEBUG
157    printk("************* SBRK 0x%08x (ret 0x%08x) **********\n", incr, rval);
158  #endif
159  return rval;
160}
161
162static void bsp_sbrk_initialize(void)
163{
164  uintptr_t overhead = _Heap_Area_overhead(CPU_HEAP_ALIGNMENT);
165  uintptr_t work_space_size = rtems_configuration_get_work_space_size();
166  ptrdiff_t sbrk_amount = bsp_sbrk_init(
167    _Memory_Get(),
168    work_space_size
169      + overhead
170      + (rtems_configuration_get_unified_work_area() ? 0 : overhead)
171  );
172
173  rtems_heap_set_sbrk_amount(sbrk_amount);
174}
175
176RTEMS_SYSINIT_ITEM(
177  bsp_sbrk_initialize,
178  RTEMS_SYSINIT_SBRK,
179  RTEMS_SYSINIT_ORDER_MIDDLE
180);
181
182#endif /* CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK */
Note: See TracBrowser for help on using the repository browser.