Blame view

build4/epsilon-master/ion/src/device/boot/rt0.cpp 2.45 KB
6663b6c9   adorian   projet complet av...
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  extern "C" {
  #include "rt0.h"
  }
  #include <stdint.h>
  #include <string.h>
  #include <ion.h>
  #include "../device.h"
  #include "../console.h"
  
  typedef void (*cxx_constructor)();
  
  extern "C" {
    extern char _data_section_start_flash;
    extern char _data_section_start_ram;
    extern char _data_section_end_ram;
    extern char _bss_section_start_ram;
    extern char _bss_section_end_ram;
    extern cxx_constructor _init_array_start;
    extern cxx_constructor _init_array_end;
  }
  
  void abort() {
  #if DEBUG
    while (1) {
    }
  #else
    Ion::Device::coreReset();
  #endif
  }
  
  void start() {
    // This is where execution starts after reset.
    // Many things are not initialized yet so the code here has to pay attention.
  
    /* Copy data section to RAM
     * The data section is R/W but its initialization value matters. It's stored
     * in Flash, but linked as if it were in RAM. Now's our opportunity to copy
     * it. Note that until then the data section (e.g. global variables) contains
     * garbage values and should not be used. */
    size_t dataSectionLength = (&_data_section_end_ram - &_data_section_start_ram);
    memcpy(&_data_section_start_ram, &_data_section_start_flash, dataSectionLength);
  
    /* Zero-out the bss section in RAM
     * Until we do, any uninitialized global variable will be unusable. */
    size_t bssSectionLength = (&_bss_section_end_ram - &_bss_section_start_ram);
    memset(&_bss_section_start_ram, 0, bssSectionLength);
  
    /* Initialize the FPU as early as possible.
     * For example, static C++ objects are very likely to manipulate float values */
    Ion::Device::initFPU();
  
    /* Call static C++ object constructors
     * The C++ compiler creates an initialization function for each static object.
     * The linker then stores the address of each of those functions consecutively
     * between _init_array_start and _init_array_end. So to initialize all C++
     * static objects we just have to iterate between theses two addresses and
     * call the pointed function. */
  #define SUPPORT_CPP_GLOBAL_CONSTRUCTORS 0
  #if SUPPORT_CPP_GLOBAL_CONSTRUCTORS
    for (cxx_constructor * c = &_init_array_start; c<&_init_array_end; c++) {
      (*c)();
    }
  #else
    /* In practice, static initialized objects are a terrible idea. Since the init
     * order is not specified, most often than not this yields the dreaded static
     * init order fiasco. How about bypassing the issue altogether? */
    if (&_init_array_start != &_init_array_end) {
      abort();
    }
  #endif
  
    Ion::Device::init();
  
    ion_main(0, nullptr);
  
    abort();
  }