source: rtems/c/src/lib/libbsp/shared/bootcard.c @ 3aefd34

4.115
Last change on this file since 3aefd34 was 3aefd34, checked in by Sebastian Huber <sebastian.huber@…>, on 11/10/11 at 14:42:08

2011-11-10 Sebastian Huber <sebastian.huber@…>

PR 1924/cpukit

  • bootcard.c: Update due to API changes.
  • Property mode set to 100644
File size: 8.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_bootcard
5 *
6 * @brief Standard system startup.
7 */
8
9/*
10 *  This is the C entry point for ALL RTEMS BSPs.  It is invoked
11 *  from the assembly language initialization file usually called
12 *  start.S.  It provides the framework for the BSP initialization
13 *  sequence.  The basic flow of initialization is:
14 *
15 *  + start.S: basic CPU setup (stack, zero BSS)
16 *    + boot_card
17 *      + bspstart.c: bsp_start - more advanced initialization
18 *      + obtain information on BSP memory and allocate RTEMS Workspace
19 *      + rtems_initialize_data_structures
20 *      + allocate memory to C Program Heap
21 *      + initialize C Library and C Program Heap
22 *      + bsp_pretasking_hook
23 *      + if defined( RTEMS_DEBUG )
24 *        - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
25 *      + rtems_initialize_before_drivers
26 *      + bsp_predriver_hook
27 *      + rtems_initialize_device_drivers
28 *        - all device drivers
29 *      + bsp_postdriver_hook
30 *      + rtems_initialize_start_multitasking
31 *        - 1st task executes C++ global constructors
32 *          .... appplication runs ...
33 *          - exit
34 *     + back to here eventually
35 *     + bspclean.c: bsp_cleanup
36 *
37 *  This style of initialization ensures that the C++ global
38 *  constructors are executed after RTEMS is initialized.
39 *  Thanks to Chris Johns <cjohns@plessey.com.au> for the idea
40 *  to move C++ global constructors into the first task.
41 *
42 *  COPYRIGHT (c) 1989-2011.
43 *  On-Line Applications Research Corporation (OAR).
44 *
45 *  The license and distribution terms for this file may be
46 *  found in the file LICENSE in this distribution or at
47 *  http://www.rtems.com/license/LICENSE.
48 *
49 *  $Id$
50 */
51
52#include <rtems.h>
53
54#include <bsp/bootcard.h>
55#include <rtems/bspIo.h>
56#include <rtems/malloc.h>
57
58#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
59#include <unistd.h> /* for sbrk() */
60#endif
61
62/*
63 *  At most a single pointer to the cmdline for those target
64 *  short on memory and not supporting a command line.
65 */
66const char *bsp_boot_cmdline;
67
68/*
69 *  These are the prototypes and helper routines which are used
70 *  when the BSP lets the framework handle RAM allocation between
71 *  the RTEMS Workspace and C Program Heap.
72 */
73static void bootcard_bsp_libc_helper(
74  void      *work_area_start,
75  uintptr_t  work_area_size,
76  void      *heap_start,
77  uintptr_t  heap_size,
78  uintptr_t  sbrk_amount
79)
80{
81  if ( heap_start == BSP_BOOTCARD_HEAP_USES_WORK_AREA ) {
82    if ( !rtems_configuration_get_unified_work_area() ) {
83      uintptr_t work_space_size = rtems_configuration_get_work_space_size();
84
85      heap_start = (char *) work_area_start + work_space_size;
86
87      if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) {
88        uintptr_t heap_size_default = work_area_size - work_space_size;
89
90        heap_size = heap_size_default;
91      }
92    } else {
93      heap_start = work_area_start;
94      if (heap_size == BSP_BOOTCARD_HEAP_SIZE_DEFAULT) {
95        heap_size = work_area_size;
96      }
97    }
98  }
99
100  bsp_libc_init(heap_start, heap_size, sbrk_amount);
101}
102
103/*
104 *  This is the initialization framework routine that weaves together
105 *  calls to RTEMS and the BSP in the proper sequence to initialize
106 *  the system while maximizing shared code and keeping BSP code in C
107 *  as much as possible.
108 */
109uint32_t boot_card(
110  const char *cmdline
111)
112{
113  rtems_interrupt_level  bsp_isr_level;
114  void                  *work_area_start = NULL;
115  uintptr_t              work_area_size = 0;
116  void                  *heap_start = NULL;
117  uintptr_t              heap_size = 0;
118  uintptr_t              sbrk_amount = 0;
119  uintptr_t              work_space_size = 0;
120  uint32_t               status = 0;
121
122  /*
123   * Special case for PowerPC: The interrupt disable mask is stored in SPRG0.
124   * It must be valid before we can use rtems_interrupt_disable().
125   */
126  #ifdef PPC_INTERRUPT_DISABLE_MASK_DEFAULT
127    ppc_interrupt_set_disable_mask( PPC_INTERRUPT_DISABLE_MASK_DEFAULT );
128  #endif /* PPC_INTERRUPT_DISABLE_MASK_DEFAULT */
129
130  /*
131   *  Make sure interrupts are disabled.
132   */
133  rtems_interrupt_disable( bsp_isr_level );
134
135  bsp_boot_cmdline = cmdline;
136
137  /*
138   * Invoke Board Support Package initialization routine written in C.
139   */
140  bsp_start();
141
142  /*
143   *  Find out where the block of memory the BSP will use for
144   *  the RTEMS Workspace and the C Program Heap is.
145   */
146  bsp_get_work_area(&work_area_start, &work_area_size,
147                    &heap_start, &heap_size);
148
149#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
150  /* This routine may reduce the work area size with the
151   * option to extend it later via sbrk(). If the application
152   * was configured w/o CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK then
153   * omit this step.
154   */
155  if ( rtems_malloc_sbrk_helpers ) {
156    sbrk_amount = bsp_sbrk_init(work_area_start, &work_area_size);
157    work_space_size = rtems_configuration_get_work_space_size();
158    if ( work_area_size <  work_space_size && sbrk_amount > 0 ) {
159      /* Need to use sbrk right now */
160      uintptr_t sbrk_now;
161
162      sbrk_now = (work_space_size - work_area_size) / sbrk_amount;
163      sbrk( sbrk_now * sbrk_amount );
164    }
165  }
166#else
167  if ( rtems_malloc_sbrk_helpers ) {
168    printk("Configuration error!\n"
169           "Application was configured with CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK\n"
170           "but BSP was configured w/o sbrk support\n");
171    status = 1;
172    bsp_cleanup( status );
173    return status;
174  }
175#endif
176
177  /*
178   *  If the user has configured a set of objects which will require more
179   *  workspace than is actually available, print a message indicating
180   *  such and return to the invoking initialization code.
181   *
182   *  NOTE: Output from printk() may not work at this point on some BSPs.
183   *
184   *  NOTE: Use cast to (void *) and %p since these are uintptr_t types.
185   */
186  work_space_size = rtems_configuration_get_work_space_size();
187  if ( work_area_size <= work_space_size ) {
188    printk(
189      "bootcard: work space too big for work area: %p >= %p\n",
190      (void *) work_space_size,
191      (void *) work_area_size
192    );
193    status = 1;
194    bsp_cleanup( status );
195    return status;
196  }
197
198  if ( !rtems_configuration_get_unified_work_area() ) {
199    rtems_configuration_set_work_space_start( work_area_start );
200  } else {
201    rtems_configuration_set_work_space_start( work_area_start );
202    rtems_configuration_set_work_space_size( work_area_size );
203    if ( !rtems_configuration_get_stack_allocator_avoids_work_space() ) {
204      rtems_configuration_set_stack_space_size( 0 );
205    }
206  }
207
208  #if (BSP_DIRTY_MEMORY == 1)
209    memset( work_area_start, 0xCF,  work_area_size );
210  #endif
211
212  /*
213   *  Initialize RTEMS data structures
214   */
215  rtems_initialize_data_structures();
216
217  /*
218   *  Initialize the C library for those BSPs using the shared
219   *  framework.
220   */
221  bootcard_bsp_libc_helper(
222    work_area_start,
223    work_area_size,
224    heap_start,
225    heap_size,
226    sbrk_amount
227  );
228
229  /*
230   *  All BSP to do any required initialization now that RTEMS
231   *  data structures are initialized.  In older BSPs or those
232   *  which do not use the shared framework, this is the typical
233   *  time when the C Library is initialized so malloc()
234   *  can be called by device drivers.  For BSPs using the shared
235   *  framework, this routine can be empty.
236   */
237  bsp_pretasking_hook();
238
239  /*
240   *  If debug is enabled, then enable all dynamic RTEMS debug
241   *  capabilities.
242   *
243   *  NOTE: Most debug features are conditionally compiled in
244   *        or enabled via configure time plugins.
245   */
246  #ifdef RTEMS_DEBUG
247    rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
248  #endif
249
250  /*
251   *  Let RTEMS perform initialization it requires before drivers
252   *  are allowed to be initialized.
253   */
254  rtems_initialize_before_drivers();
255
256  /*
257   *  Execute BSP specific pre-driver hook. Drivers haven't gotten
258   *  to initialize yet so this is a good chance to initialize
259   *  buses, spurious interrupt handlers, etc..
260   *
261   *  NOTE: Many BSPs do not require this handler and use the
262   *        shared stub.
263   */
264  bsp_predriver_hook();
265
266  /*
267   *  Initialize all device drivers.
268   */
269  rtems_initialize_device_drivers();
270
271  /*
272   *  Invoke the postdriver hook.  This normally opens /dev/console
273   *  for use as stdin, stdout, and stderr.
274   */
275  bsp_postdriver_hook();
276
277  /*
278   *  Complete initialization of RTEMS and switch to the first task.
279   *  Global C++ constructors will be executed in the context of that task.
280   */
281  status = rtems_initialize_start_multitasking();
282
283  /***************************************************************
284   ***************************************************************
285   *  APPLICATION RUNS HERE!!!  When it shuts down, we return!!! *
286   ***************************************************************
287   ***************************************************************
288   */
289
290  /*
291   *  Perform any BSP specific shutdown actions which are written in C.
292   */
293  bsp_cleanup( status );
294
295  /*
296   *  Now return to the start code.
297   */
298  return status;
299}
Note: See TracBrowser for help on using the repository browser.