1 /*
2 * Copyright (c) 2008 Texas Instruments. All rights reserved.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License
5 * v. 1.0 which accompanies this distribution. The Eclipse Public License is
6 * available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
7 * Distribution License is available at
8 * http://www.eclipse.org/org/documents/edl-v10.php.
9 *
10 * Contributors:
11 * Texas Instruments - initial implementation
12 * */
13 /*
14 * ======== Startup.xdc ========
15 *
16 * implemenation
17 */
18
19 package xdc.runtime;
20
21 /*!
22 * ======== Startup ========
23 * The `xdc.runtime` startup bootstrap
24 *
25 * Every module can optionally define a startup function which is called
26 * before `main()`. Modules declare that they want to participate in this
27 * startup sequence via the `@ModuleStartup` attribute in the module's spec
28 * file. Modules that use this attribute must also implement the following
29 * startup function:
30 * @p(code) 31 * Int Mod_Module_startup(Int state);
32 * @p 33 * where "Mod" is the name of the module requesting startup support.
34 *
35 * The parameter to the startup function serves as "state variable" whose
36 * initial value will be `Startup_NOTDONE`. If `startup()` returns a value
37 * other than `Startup_DONE`, it will be called in a subsequent pass with this
38 * return value passed in as `state`. To ensure this process terminates,
39 * no startup function is ever called more than `{@link #maxPasses}`
40 * times.
41 *
42 * For situations in which the startup of one module depends upon another
43 * having completed its startup processing, the following function is
44 * automatically defined for all modules and proxies:
45 * @p(code) 46 * Bool Mod_Module_startupDone();
47 * @p 48 * where "Mod" is the name of some module or proxy. These predicates can
49 * be used as guards inside of a startup function to probe whether a
50 * particular module has completed its own startup processing. As a
51 * convenience, the function `Startup_rtsDone()` probes the necessary set of
52 * `xdc.runtime` modules required to support instance `create()` functions, and
53 * should be called before any startup-time instance creation and/or
54 * memory allocation is performed.
55 * @p(code) 56 * Int Mod_Module_startup(Int state)
57 * {
58 * if (!Startup_rtsDone()) {
59 * return (Startup_NOTDONE);
60 * }
61 * .
62 * .
63 * .
64 * return (Startup_DONE);
65 * }
66 * @p 67 *
68 * @a(Startup Sequence) 69 * The following list defines when in the startup sequence the user provided
70 * startup functions are being invoked:
71 * @p(nlist) 72 * - CPU is initialized and C stack setup is performed.
73 * - Function specified by `Startup.resetFxn` is called.
74 * `Startup.resetFxn` is called only on platforms where reset is performed
75 * before running a program. For example, boot code for all TI targets
76 * invokes `Startup.resetFxn`, while that function is not invoked on
77 * Microsoft targets.
78 * - C runtime initialization is performed.
79 * - Functions from the array `Startup.firstFxns` are called.
80 * - All `Mod_Module_startup` functions are called in a loop until all such
81 * functions return `Startup_DONE` or `maxPasses` threshold is reached.
82 * - Functions from the array `Startup.lastFxns` are called.
83 * - The function `main` is called.
84 * @p 85 * The steps 4 - 6 occur during C++ static object initialization. Since
86 * the ANSI C++ Language Standard does not provide a means to control
87 * the order of C++ constructors, if a C++ constructor uses an XDC module,
88 * there is no guarantee that the module's startup function already ran.
89 * Therefore, any C++ constructor that needs XDC modules' services should
90 * call `Startup_exec` first to force all startup related functions from
91 * steps 4 - 6 to run, before the constructor uses any XDC module.
92 * @p 93 * Also, if a target does not support C++, the steps 4 - 6 will not run
94 * automatically. It is then up to a user's code to invoke `Startup_exec`,
95 * possibly as the first step in `main`.
96 * @p 97 */
98 @Template("./Startup.xdt")
99
100 module Startup {
101
102 /*!
103 * ======== DONE ========
104 * Returned from module startup functions no further calls are required
105 */
106 const Int DONE = -1;
107
108 /*!
109 * ======== NOTDONE ========
110 * Initial value of state argument passed to module startup functions
111 */
112 const Int NOTDONE = 0;
113
114 /*!
115 * ======== maxPasses ========
116 * Max number of iterations over the set of startup functions
117 */
118 config Int maxPasses = 32;
119
120 /*!
121 * ======== InitFxn ========
122 * Type of function assignable to `firstFxns`, `lastFxns`, or `resetFxn`
123 */
124 typedef Void (*InitFxn)();
125
126 /*!
127 * ======== firstFxns ========
128 * List of functions called before module startup
129 *
130 */
131 config InitFxn firstFxns[length] = [];
132
133 /*!
134 * ======== lastFxns ========
135 * List of functions called after module startup
136 *
137 */
138 config InitFxn lastFxns[length] = [];
139
140 /*!
141 * ======== resetFxn ========
142 * Function to be called by during initialization
143 *
144 * This function is called only on platforms where reset is performed
145 * before running the program. The purpose of this function is to set up
146 * the hardware registers (cache, external memory interface, etc.) before
147 * any other code executes.
148 *
149 */
150 metaonlyconfig InitFxn resetFxn = null;
151
152 /*!
153 * ======== exec ========
154 * Execute the startup functions of all resident modules
155 *
156 * Note that this function is idempotent, and can be called at any point
157 * in the platform/target startup sequence in which "ordinary" C functions
158 * can execute. By default, this function is called as part of the
159 * standard C++ static initialization sequence.
160 *
161 * If your target compiler does not support C++, this function must be
162 * called at least once prior to using any `xdc.runtime` modules.
163 * Simply call this function at the very beginning of `main()`.
164 */
165 Void exec();
166
167 /*!
168 * ======== rtsDone ========
169 * Query the state of the `xdc.runtime` package
170 *
171 * This function is used by module startup functions to determine
172 * when it is possible to use the `xdc.runtime` modules; e.g. to
173 * allocate memory, create instances managed by some module (even
174 * those outside the `xdc.runtime` package), call a `Log` function,
175 * etc.
176 *
177 * @a(returns) 178 * Returns `TRUE` when all `xdc.runtime` modules have completed
179 * initialization.
180 */
181 Bool rtsDone();
182
183 internal:
184
185 /*!
186 * ======== reset ========
187 * Application-specific reset function
188 *
189 * This function is defined in `Startup.xdt`
190 * (`xdc_runtime_Startup_reset__I`) and is called as early as
191 * possible in the program initialization process; for many platforms,
192 * it is called prior the the initialization of the C runtime
193 * environment.
194 */
195 Void reset();
196
197 Void startMods(Int state[], Int len);
198 readonlyconfig Void (*startModsFxn)(Int[], Int) = startMods;
199
200 extern Void execImplFxn() = xdc_runtime_Startup_exec__I;
201
202 readonlyconfig Void (*execImpl)() = execImplFxn;
203
204 typedef Int (*SFxn)(Int);
205 config SFxn sfxnTab[];
206
207 /*!
208 * ======== sfxnRts ========
209 * Array of runtime modules' startup functions
210 *
211 * This array also contains startup functions of the modules that inherit
212 * from interfaces in `xdc.runtime`. Functions added to this array are
213 * called only once before the startup procedure for all modules begins.
214 */
215 config Bool sfxnRts[];
216
217 struct Module_State {
218 Int *stateTab; /* initially null */
219 Bool execFlag; /* if true, startup code processing started */
220 Bool rtsDoneFlag;
221 };
222
223 }
224 /*
225 * @(#) xdc.runtime; 2, 0, 0, 0,207; 6-9-2009 20:10:18; /db/ztree/library/trees/xdc-t50x/src/packages/
226 */
227