summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/dmv177/startup/rtems-ctor.cc
blob: 0c7efef5925c1136269eb3b0305853f21732ae85 (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 *  rtems-ctor.cc
 *
 *  Description:
 *	This file exists solely to (try to) ensure RTEMS is initialized
 *      before any global constructors are run.
 *
 *  The problem:
 *      Global constructors might reasonably expect that new() will
 *      work, but since new() uses malloc() which uses RTEMS regions,
 *      it can not be called until after initialize_executive().
 *
 *      Global constructors are called in GNU systems one of 2 ways:
 *
 *              an "invisible" call to __main() inserted by compiler
 *              This __main() calls __do_global_ctors() which
 *              walks thru the table and calls all global
 *              constructors.
 *
 *       or -
 *              A special section is put into the linked binary.  The
 *              system startup code knows to run the constructors in
 *              this special section before calling main().
 *
 *      By making RTEMS initialization a constructor, we avoid having
 *      too much about all this.  All we have to guarantee is that
 *      this constructor is the first one run.
 *
 *
 *  So for the first case above, this is what happens
 *
 *    host crt0
 *      main()
 *          __main()
 *              __do_global_ctors()
 *                  bsp_start()
 *                      init_executive_early()
 *                  <<any other constructors>>
 *
 *          rtems_init_executive_late()
 *          bsp_cleanup()
 *
 *  TODO:
 *
 *  COPYRIGHT (c) 1989-1998.
 *  On-Line Applications Research Corporation (OAR).
 *  Copyright assigned to U.S. Government, 1994.
 *
 *  The license and distribution terms for this file may in
 *  the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 *  $Id$
 */

#include <bsp.h>

/*
 * RTEMS program name
 * Probably not used by anyone, but it is nice to have it.
 * Actually the UNIX version of CPU_INVOKE_DEBUGGER will probably
 * need to use it
 */

char *rtems_progname;
char **rtems_environp;

#ifdef USE_CONSTRUCTORS_FOR_INIT_EXEC

class RTEMS {
    public:
	RTEMS();
        ~RTEMS();
};

RTEMS  rtems_constructor;


/*  PAGE
 *
 *  RTEMS::RTEMS
 *
 *  RTEMS constructor routine
 *
 *  Input parameters:  NONE
 *
 *  Output parameters:  NONE
 *
 *  Return values:  NONE
 */

RTEMS::RTEMS()
{
    bsp_start();
}

/*  PAGE
 *
 *  RTEMS::~RTEMS
 *
 *  RTEMS distructor routine
 *
 *  Input parameters:  NONE
 *
 *  Output parameters:  NONE
 *
 *  Return values:  NONE
 */

RTEMS::~RTEMS()
{
    bsp_cleanup();
}
#endif

extern "C" {
    int
    main(int argc,
         char **argv,
         char **environp)
    {

#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC
        bsp_start();
#endif

        if ((argc > 0) && argv && argv[0])
            rtems_progname = argv[0];
        else
            rtems_progname = "RTEMS";

        rtems_environp = environp;

        /*
         *  Start multitasking
         */

        rtems_initialize_executive_late( bsp_isr_level );

#ifndef USE_CONSTRUCTORS_FOR_INIT_EXEC
        bsp_cleanup();
#endif

        /*
         * Returns when multitasking is stopped
         * This allows our destructors to get run normally
         */

        return 0;
    }
}