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