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 package ti.sysbios.family.c64p;
38
39 import xdc.rov.ViewInfo;
40 import xdc.runtime.Error;
41 import xdc.runtime.Diags;
42 import xdc.runtime.Log;
43
44 /*!
45 * ======== Exception ========
46 * Exception Module
47 *
48 * The Exception module is a basic C64+ exception handler. It is generally
49 * considered to be a program endpoint, since an exception usually
50 * indicates something fatal to the system.
51 *
52 * During initialization, the Exception module sets TSR.GEE and TSR.XEN to
53 * enable the CPU to recognize the EXECP input.
54 *
55 * Function hooks are provided to the user for hooking in their own functions
56 * at different points of an exception. The hook functions are called in the
57 * following order:
58 * (1) exceptionHook - called whenever an exception occurs.
59 * (2) internalHook - called only when an internal exception occurs.
60 * (3) externalHook - called only when an external exception occurs.
61 * (4) nmiHook - called only when a legacy NMI occurs.
62 * (5) returnHook - called whenever an exception occurs.
63 *
64 * @p(html)
65 * <h3> Calling Context </h3>
66 * <table border="1" cellpadding="3">
67 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
68 *
69 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
70 * <!-- -->
71 * <tr><td> {@link #clearLastStatus} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
72 * <tr><td> {@link #evtEvtClear} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
73 * <tr><td> {@link #evtExpMaskEnable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
74 * <tr><td> {@link #getLastStatus} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
75 * <tr><td> {@link #setReturnPtr} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
76 * <tr><td colspan="6"> Definitions: <br />
77 * <ul>
78 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
79 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
80 * <li> <b>Task</b>: API is callable from a Task thread. </li>
81 * <li> <b>Main</b>: API is callable during any of these phases: </li>
82 * <ul>
83 * <li> In your module startup after this module is started (e.g. Mod_Module_startupDone() returns TRUE). </li>
84 * <li> During xdc.runtime.Startup.lastFxns. </li>
85 * <li> During main().</li>
86 * <li> During BIOS.startupFxns.</li>
87 * </ul>
88 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
89 * <ul>
90 * <li> During xdc.runtime.Startup.firstFxns.</li>
91 * <li> In your module startup before this module is started (e.g. Mod_Module_startupDone() returns FALSE).</li>
92 * </ul>
93 * </ul>
94 * </td></tr>
95 *
96 * </table>
97 * @p
98 */
99
100 @ModuleStartup
101 @DirectCall
102 module Exception
103 {
104 /*! @_nodoc */
105 metaonly struct ModuleView {
106 String exception;
107 };
108
109 /*!
110 * ======== rovViewInfo ========
111 * @_nodoc
112 */
113 @Facet
114 metaonly config ViewInfo.Instance rovViewInfo =
115 ViewInfo.create({
116 viewMap: [
117 ['Exception',
118 {
119 type: ViewInfo.TREE,
120 viewInitFxn: 'viewInitException',
121 structName: 'Context'
122 }
123 ],
124 ['Module',
125 {
126 type: ViewInfo.MODULE,
127 viewInitFxn: 'viewInitModule',
128 structName: 'ModuleView'
129 }
130 ]
131 ]
132 });
133
134
135
136 /*! FuncPtr - Hook function type definition. */
137 typedef Void (*FuncPtr)(void);
138
139 /*! @_nodoc
140 * Context - Register contents at the time of the exception.
141 * dispatch() creates a Context structure on the Hwi ISR stack or
142 * context buffer and fills it before calling handler. A pointer
143 * to this Context structure is returned by getLastStatus().
144 */
145 struct Context {
146 Ptr ILC; //! register ILC
147 Ptr RILC; //! register RILC
148 Ptr AMR; //! register AMR
149 Ptr SSR; //! register SSR
150 Ptr IRP; //! register IRP
151 Ptr NRP; //! register NRP
152 Ptr ITSR; //! register ITSR
153 Ptr NTSR; //! register NTSR
154 Ptr EFR; //! register EFR
155 Ptr IERR; //! register IERR
156 Ptr B30; //! general purpose register b30
157 Ptr B31; //! general purpose register b31
158 Ptr B28; //! general purpose register b28
159 Ptr B29; //! general purpose register b29
160 Ptr B26; //! general purpose register b26
161 Ptr B27; //! general purpose register b27
162 Ptr B24; //! general purpose register b24
163 Ptr B25; //! general purpose register b25
164 Ptr B22; //! general purpose register b22
165 Ptr B23; //! general purpose register b23
166 Ptr B20; //! general purpose register b20
167 Ptr B21; //! general purpose register b21
168 Ptr B18; //! general purpose register b18
169 Ptr B19; //! general purpose register b19
170 Ptr B16; //! general purpose register b16
171 Ptr B17; //! general purpose register b17
172 Ptr B14; //! general purpose register b14
173 Ptr B15; //! general purpose register b15
174 Ptr B12; //! general purpose register b12
175 Ptr B13; //! general purpose register b13
176 Ptr B10; //! general purpose register b10
177 Ptr B11; //! general purpose register b11
178 Ptr B8; //! general purpose register b8
179 Ptr B9; //! general purpose register b9
180 Ptr B6; //! general purpose register b6
181 Ptr B7; //! general purpose register b7
182 Ptr B4; //! general purpose register b4
183 Ptr B5; //! general purpose register b5
184 Ptr B2; //! general purpose register b2
185 Ptr B3; //! general purpose register b3
186 Ptr B0; //! general purpose register b0
187 Ptr B1; //! general purpose register b1
188 Ptr A30; //! general purpose register a30
189 Ptr A31; //! general purpose register a31
190 Ptr A28; //! general purpose register a28
191 Ptr A29; //! general purpose register a29
192 Ptr A26; //! general purpose register a26
193 Ptr A27; //! general purpose register a27
194 Ptr A24; //! general purpose register a24
195 Ptr A25; //! general purpose register a25
196 Ptr A22; //! general purpose register a22
197 Ptr A23; //! general purpose register a23
198 Ptr A20; //! general purpose register a20
199 Ptr A21; //! general purpose register a21
200 Ptr A18; //! general purpose register a18
201 Ptr A19; //! general purpose register a19
202 Ptr A16; //! general purpose register a16
203 Ptr A17; //! general purpose register a17
204 Ptr A14; //! general purpose register a14
205 Ptr A15; //! general purpose register a15
206 Ptr A12; //! general purpose register a12
207 Ptr A13; //! general purpose register a13
208 Ptr A10; //! general purpose register a10
209 Ptr A11; //! general purpose register a11
210 Ptr A8; //! general purpose register a8
211 Ptr A9; //! general purpose register a9
212 Ptr A6; //! general purpose register a6
213 Ptr A7; //! general purpose register a7
214 Ptr A4; //! general purpose register a4
215 Ptr A5; //! general purpose register a5
216 Ptr A2; //! general purpose register a2
217 Ptr A3; //! general purpose register a3
218 Ptr A0; //! general purpose register a0
219 Ptr A1; //! general purpose register a1
220 };
221
222 /*! Status - structure filled by getLastStatus(). */
223 struct Status {
224 Bits32 efr; //! Exception flag register
225 Bits32 nrp; //! NMI return pointer register
226 Bits32 ntsr; //! NMI/Exception task state register
227 Bits32 ierr; //! Internal Exception report register
228 Context *excContext;//! Context structure filled by last exception
229 };
230
231
232
233 234 235
236 const Bits32 EFRSXF = 0x00000001; //! Software exception flag
237 const Bits32 EFRIXF = 0x00000002; //! Internal exception flag
238 const Bits32 EFREXF = 0x40000000; //! EXCEP flag
239 const Bits32 EFRNXF = 0x80000000; //! NMI exception flag
240
241 242 243
244 const Bits32 ECRSXF = EFRSXF; //! Software exception flag
245 const Bits32 ECRIXF = EFRIXF; //! Internal exception flag
246 const Bits32 ECREXF = EFREXF; //! EXCEP flag
247 const Bits32 ECRNXF = EFRNXF; //! NMI exception flag
248
249 250 251
252 const Bits32 IERRIFX = 0x00000001; //! Instruction fetch exception
253 const Bits32 IERRFPX = 0x00000002; //! Fetch packet exception
254 const Bits32 IERREPX = 0x00000004; //! Execute packet exception
255 const Bits32 IERROPX = 0x00000008; //! Opcode exception
256 const Bits32 IERRRCX = 0x00000010; //! Resource conflict exception
257 const Bits32 IERRRAX = 0x00000020; //! Resource access exeption
258 const Bits32 IERRPRX = 0x00000040; //! Priviledge exception
259 const Bits32 IERRLBX = 0x00000080; //! Loop buffer exception
260 const Bits32 IERRMSX = 0x00000100; //! Missed stall exception
261
262 263 264
265 const Bits32 TSRGEE = 0x00000004; //! Global exception enable
266 const Bits32 TSRXEN = 0x00000008; //! External exception enable
267 const Bits32 TSREXC = 0x00000400; //! Exception processing
268
269
270 const Bits32 TSRCXM = 0x000000C0; //! Current execution mode bits
271 const Bits32 TSRCXMSHIFT = 6; //! TSR.CXM left shift value
272 const Bits32 TSRCXMSV = 0x00000000; //! Supervisor mode
273 const Bits32 TSRCXMUS = 0x00000040; //! User mode
274
275
276 const UInt32 sizeContextBuf = 320;
277
278 /*! Error raised when {@link #enablePrint Exception.enablePrint} is false */
279 config Error.Id E_exceptionMin = {
280 msg: "E_exceptionMin: pc = 0x%08x, sp = 0x%08x.\nTo see more exception detail, use ROV or set 'ti.sysbios.family.c64p.Exception.enablePrint = true;'"
281 };
282
283 /*! Error raised when {@link #enablePrint Exception.enablePrint} is true */
284 config Error.Id E_exceptionMax = {
285 msg: "E_exceptionMax: pc = 0x%08x, sp = 0x%08x."
286 };
287
288
289
290 /*!
291 * If true, the exception context is saved to an internal buffer.
292 * If false, the exception context is saved to the bottom of the isr stack
293 * and no memory for the internal buffer is allocated.
294 */
295 config Bool useInternalBuffer = false;
296
297 /*!
298 * enableExternalMPC - Enable handling of Memory Protection
299 * Controller (MPC) exceptions.
300 */
301 config Bool enableExternalMPC = false;
302
303 /*!
304 * enablePrint - Enable print of exception details and Register values
305 */
306 config Bool enablePrint = true;
307
308 /*!
309 * exceptionHook - Function hook called by handler
310 * This is called anytime an exception occurs.
311 */
312 config FuncPtr exceptionHook = null;
313
314 /*!
315 * internalHook - Function hook called by internalHandler
316 * Function is only called when an internal exception has occurred.
317 */
318 config FuncPtr internalHook = null;
319
320 /*!
321 * externalHook - Function hook called by externalHandler
322 * Function is only called when an external exception has occurred.
323 */
324 config FuncPtr externalHook = null;
325
326 /*!
327 * nmiHook - Function hook called by nmiHandler
328 * Function is called for legacy NMI exceptions only
329 */
330 config FuncPtr nmiHook = null;
331
332 /*! returnHook - Function hook called at the end of Exception_dispatch */
333 config FuncPtr returnHook = null;
334
335 /*!
336 * getLastStatus - Fills passed status structure with the Status
337 * fields that were recorded by the last invocation of
338 * dispatch(), handler() and internalHandler().
339 * The 'excContext' is valid only in the scope of sub-handler
340 * "Hook" functions.
341 */
342 Void getLastStatus(Status *status);
343
344 /*!
345 * clearLastStatus - Clears internal Status structure.
346 */
347 Void clearLastStatus();
348
349 /*!
350 * setReturnPtr - Configures dispatch() to "return" (branch) to the
351 * passed ptr.
352 */
353 FuncPtr setReturnPtr(FuncPtr ptr);
354
355 /*!
356 * evtEvtClear - Clear a C64+ event from the EVTFLAG register.
357 */
358 Void evtEvtClear(UInt event);
359
360 /*!
361 * evtExpMaskEnable - Enable a C64+ event to generate an exception.
362 */
363 Void evtExpMaskEnable(UInt event);
364
365 /*! @_nodoc
366 * dispatch - The default low-level dispatcher, plugged into the
367 * C64+ NMI vector.
368 */
369 Void dispatch();
370
371 internal:
372
373
374 const UInt EVTPMCCMPA = 120;
375 const UInt EVTDMCCMPA = 122;
376 const UInt EVTUMCCMPA = 124;
377 const UInt EVTEMCCMPA = 126;
378
379 /*!
380 * handler - The high-level dispatcher, called by dispatch().
381 * Performs the following steps in order:
382 * a. records EFR/NRP/NTSR in a Status structure
383 * b. logs EFR/NRP/NTSR.CXM with text output to module's logger
384 * c. calls exceptionHook
385 * d. clears EFR
386 * e. calls into subhandlers
387 * f. aborts system
388 */
389 Void handler(Bool abortFlag);
390
391 /*!
392 * internalHandler - Internal exception handler called by
393 * handler(). Performs the following steps in order:
394 * a. records IERR in a Status structure
395 * b. logs IERR with text output to module's logger
396 * c. calls internalHook
397 * d. clears IERR
398 */
399 Void internalHandler();
400
401 /*!
402 * externalHandler - External exception handler called by
403 * handler(). Performs the following steps in order:
404 * a. logs text output to module's logger
405 * b. calls externalHook
406 */
407 Void externalHandler();
408
409 /*!
410 * nmiHandler - Legacy NMI handler called by handler().
411 * Performs the following steps in order:
412 * a. logs text output to module's logger
413 * b. calls nmiHook
414 */
415 Void nmiHandler();
416
417 418 419
420 Void decodeMpfsr(UInt mpfsr);
421
422 struct Module_State {
423 Bits32 efr;
424 Bits32 nrp;
425 Bits32 ntsr;
426 Bits32 ierr;
427 FuncPtr returnHook;
428 Context *excContext;
429 Char scratch[16];
430 Char *excPtr;
431 Char contextBuf[];
432 };
433 }
434