1    /*
     2     * Copyright (c) 2015, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== Exception.xdc ========
    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         /* generate a call to Exception at startup */
   101    @DirectCall
   102    module Exception
   103    {
   104        /*! @_nodoc */
   105        metaonly struct ModuleView {
   106            String      exception;      /* Summary 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        // -------- Module Types --------
   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        // -------- Module Constants --------
   232    
   233        /*
   234         *  Bitmasks for C64+ Exception Flag Register (EFR).
   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         *  Bitmasks for C64+ Exception Clear Register (ECR).
   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         *  Bitmasks for C64+ Internal Exception Report Register (IERR).
   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         *  Exception-related bitmasks for C64+ Task State Register (TSR).
   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        /* TSR Privilege Mode bits */
   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        /* size of buffer (in bytes) to hold exception context */
   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        // -------- Module Parameters --------
   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        /* MPC CPU Access Memory Protecton Fault Event numbers */
   374        const UInt EVTPMCCMPA = 120;        /* PMC memory protection fault event */
   375        const UInt EVTDMCCMPA = 122;        /* DMC memory protection fault event */
   376        const UInt EVTUMCCMPA = 124;        /* UMC memory protection fault event */
   377        const UInt EVTEMCCMPA = 126;        /* EMC memory protection fault event */
   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         *  ======== decodeMpfsr ========
   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];    // sratch memory used by dispatch
   430            Char    *excPtr;        // points to isrStack or contextBuf
   431            Char    contextBuf[];   // Need at least 74 words for context buf
   432        };
   433    }
   434