1    /*
     2     * Copyright (c) 2016-2020, 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     *  ======== Mmu.xdc ========
    34     */
    35    
    36    package ti.sysbios.family.c7x;
    37    
    38    /*!
    39     *  ======== Mmu ========
    40     *  Memory Management Unit (MMU) Manager
    41     *
    42     *  This module allows the C7x processor to map a 64-bit virtual address
    43     *  to a 48-bit physical address and enable/disable the MMU. It does this
    44     *  through translation tables in memory.
    45     *
    46     *  Every application must register a Mmu init function (see {@link #initFunc})
    47     *  that contains calls to Mmu_map() to configure the MMU.
    48     *
    49     *  *.cfg:
    50     *  @p(code)
    51     *  var Mmu = xdc.useModule('ti.sysbios.family.c7x.Mmu');
    52     *  Mmu.initFunc = "&Mmu_initFuncDefault";
    53     *  @p
    54     *
    55     *  Example {@link #initFuncDefault Mmu_initFuncDefault()} provided
    56     *  function for J7 devices:
    57     *  @p(code)
    58     *  ...
    59     *
    60     *  Void Mmu_initFuncDefault()
    61     *  {
    62     *      Bool ret;
    63     *      Mmu_MapAttrs attrs;
    64     *
    65     *      Mmu_initMapAttrs(&attrs);
    66     *
    67     *      // MAIR0 has a default memory type that is non-gathering and
    68     *      // non-reordering with no early write acknowledegement property.
    69     *      // In other words, strongly ordered memory type.
    70     *      attrs.attrIndx = Mmu_AttrIndx_MAIR0;
    71     *
    72     *      // Map GICv3 registers
    73     *      ret = Mmu_map(0x01800000, 0x01800000, 0x00100000, &attrs);
    74     *      if (!ret) {
    75     *          goto fail;
    76     *      }
    77     *
    78     *      // Map DMTimer registers
    79     *      ret = Mmu_map(0x02400000, 0x02400000, 0x000c0000, &attrs);
    80     *      if (!ret) {
    81     *          goto fail;
    82     *      }
    83     *
    84     *      // Map UART registers
    85     *      ret = Mmu_map(0x02800000, 0x02800000, 0x00001000, &attrs);
    86     *      if (!ret) {
    87     *          goto fail;
    88     *      }
    89     *
    90     *      // Map System Timer registers
    91     *      ret = Mmu_map(0x2A430000, 0x2A430000, 0x00001000, &attrs);
    92     *      if (!ret) {
    93     *          goto fail;
    94     *      }
    95     *
    96     *      // MAIR7 has a default attribute type of Inner and Outer
    97     *      // write-back cacheable
    98     *      attrs.attrIndx = Mmu_AttrIndx_MAIR7;
    99     *
   100     *      //Map MSMC SRAM
   101     *      ret = Mmu_map(0x70000000, 0x70000000, 0x00200000, &attrs);
   102     *      if (!ret) {
   103     *          goto fail;
   104     *      }
   105     *
   106     *      return;
   107     *
   108     *  fail:
   109     *      System_printf("Mmu config failed.\n");
   110     *      while (1);
   111     *  }
   112     *
   113     *  @p
   114     */
   115    
   116    @DirectCall
   117    @Template ("./Mmu.xdt")
   118    
   119    module Mmu
   120    {
   121        const UInt8 PA_MAX_WIDTH = 48;
   122    
   123        /*
   124         * Default: 48-bits, 256TB
   125         */
   126        const UInt8 PA_SIZE_ENCODING = 0x5;
   127    
   128        // -------- ROV views --------
   129    
   130        //TBD
   131    
   132        /*!
   133         *  ======== AttrIndx ========
   134         *  Memory attribute register (MAIR) index
   135         *
   136         *  SYS/BIOS defines default values for MAIR register. See {@link #MAIR0},
   137         *  {@link #MAIR1}, {@link #MAIR2}, {@link #MAIR3}, {@link #MAIR4},
   138         *  {@link #MAIR5}, {@link #MAIR6} & {@link #MAIR7} for more info on the
   139         *  memory type defined by each MAIR register.
   140         */
   141        enum AttrIndx {
   142            AttrIndx_MAIR0 = 0,
   143            AttrIndx_MAIR1,
   144            AttrIndx_MAIR2,
   145            AttrIndx_MAIR3,
   146            AttrIndx_MAIR4,
   147            AttrIndx_MAIR5,
   148            AttrIndx_MAIR6,
   149            AttrIndx_MAIR7
   150        };
   151    
   152        /*!
   153         *  @_nodoc
   154         *  ======== DescriptorType ========
   155         *  Different descriptor type encodings:
   156         *  @p(blist)
   157         *  - Invalid or Fault entry (0b00 or 0b10)
   158         *  - Block descriptor entry (0b01)
   159         *  - Table descriptor entry (0b11)
   160         *  @p
   161         */
   162        enum DescriptorType {
   163            DescriptorType_INVALID0 = 0,   /*! Virtual address is unmapped     */
   164            DescriptorType_BLOCK = 1,      /*! Block descriptor                */
   165            DescriptorType_INVALID1 = 2,   /*! Virtual address is unmapped     */
   166            DescriptorType_TABLE = 3       /*! Next-level table address        */
   167        };
   168    
   169        /*!
   170         *  ======== GranuleSize ========
   171         *  Memory translation {@link #granuleSize} granule size
   172         */
   173        enum GranuleSize {
   174            GranuleSize_4KB = 0x1000,
   175            GranuleSize_16KB = 0x4000,
   176            GranuleSize_64KB = 0x10000
   177        };
   178    
   179        /*!
   180         *  ======== Shareable ========
   181         *  Shareability attribute
   182         */
   183        enum Shareable {
   184            Shareable_NONE = 0x0,
   185            Shareable_OUTER = 0x2,
   186            Shareable_INNER = 0x3
   187        };
   188    
   189        /*!
   190         *  ======== AccessPerm ========
   191         *  Access Permissions
   192         */
   193        enum AccessPerm {
   194            AccessPerm_PRIV_RW_USER_NONE = 0x0, /* Privileged Read/write (EL1),
   195                                                   User no access (EL0) */
   196            AccessPerm_PRIV_RW_USER_RW = 0x1,   /* Privileged Read/write (EL1),
   197                                                   User Read/write (EL0) */
   198            AccessPerm_PRIV_RO_USER_NONE = 0x2, /* Privileged Read only (EL1),
   199                                                   User no access (EL0) */
   200            AccessPerm_PRIV_RO_USER_RO = 0x3    /* Privileged Read only (EL1),
   201                                                   User Read only (EL0) */
   202        };
   203    
   204        /*! Mmu init function type definition. */
   205        typedef Void (*InitFuncPtr)(void);
   206    
   207        /*!
   208         *  ======== MapAttrs ========
   209         *  Structure containing attributes for memory map entry
   210         */
   211        struct MapAttrs {
   212            Bool       ns;
   213            AccessPerm accessPerm;      /*! privileged & user access permissions  */
   214            Bool       privExecute;     /*! privileged execute permission         */
   215            Bool       userExecute;     /*! user execute permission               */
   216            Shareable  shareable;       /*! shareability field value 0-3          */
   217            AttrIndx   attrIndx;        /*! stage 1 memory attributes index field
   218                                            for the indicated MAIRn reg value 0-7 */
   219            Bool       global;          /*! global mmu entry ? (used by kernel
   220                                            when memory protection extensions are
   221                                            enabled)                              */
   222        };
   223    
   224        // Asserts
   225    
   226        /*!
   227         *  ======== A_nullPointer ========
   228         *  Assert raised when a pointer is null
   229         */
   230        config xdc.runtime.Assert.Id A_nullPointer  = {
   231            msg: "A_nullPointer: Pointer is null"
   232        };
   233    
   234        /*!
   235         *  ======== A_vaddrOutOfRange ========
   236         *  Assert raised when virtual address passed is out of range
   237         */
   238        config xdc.runtime.Assert.Id A_vaddrOutOfRange  = {
   239            msg: "A_vaddrOutOfRange: Virtual address is out of range"
   240        };
   241    
   242        /*!
   243         *  ======== A_paddrOutOfRange ========
   244         *  Assert raised when physical address passed is out of range
   245         */
   246        config xdc.runtime.Assert.Id A_paddrOutOfRange  = {
   247            msg: "A_paddrOutOfRange: Physical address is out of range"
   248        };
   249    
   250        /*!
   251         *  ======== A_unalignedVaddr ========
   252         *  Assert raised if unaligned virtual address passed to Mmu_map().
   253         */
   254        config xdc.runtime.Assert.Id A_unalignedVaddr =
   255            {msg: "A_unalignedVaddr: Virtual address not page aligned"};
   256    
   257        /*!
   258         *  ======== A_unalignedPaddr ========
   259         *  Assert raised if unaligned physical address passed to Mmu_map().
   260         */
   261    
   262        config xdc.runtime.Assert.Id A_unalignedPaddr =
   263            {msg: "A_unalignedPaddr: Physical address not page aligned"};
   264    
   265        /*!
   266         *  ======== A_unalignedSize ========
   267         *  Assert raised if unaligned size passed to Mmu_map().
   268         */
   269        config xdc.runtime.Assert.Id A_unalignedSize =
   270            {msg: "A_unalignedSize: Mmu mapping size not page aligned"};
   271    
   272        /*!
   273         *  ======== defaultMapAttrs ========
   274         *  default descriptor attributes structure
   275         */
   276        config MapAttrs defaultMapAttrs = {
   277            ns: 1,
   278            accessPerm: AccessPerm_PRIV_RW_USER_NONE,
   279            privExecute: true,
   280            userExecute: false,
   281            shareable: Shareable_OUTER,
   282            attrIndx: AttrIndx_MAIR0,
   283            global: true
   284        };
   285    
   286        /*!
   287         *  ======== enableMMU ========
   288         *  Configuration parameter to enable MMU.
   289         */
   290        config Bool enableMMU = true;
   291    
   292        /*!
   293         *  ======== granuleSize ========
   294         *  Memory translation granule size. Default is 4KB.
   295         *
   296         *  The granule size determines the smallest page size that can be
   297         *  mapped with the MMU.
   298         */
   299        config GranuleSize granuleSize = GranuleSize_4KB;
   300    
   301        /*!
   302         *  ======== MAIR0 ========
   303         *  Memory attribute 0.
   304         *
   305         *  Default is memory with non-gathering, non-reordering and no early write
   306         *  acknowledegement property.
   307         */
   308        config UInt8 MAIR0 = 0x00;
   309    
   310        /*!
   311         *  ======== MAIR1 ========
   312         *  Memory attribute 1
   313         *
   314         *  Default is memory with non-gathering, non-reordering and early write
   315         *  acknowledegement property.
   316         */
   317        config UInt8 MAIR1 = 0x04;
   318    
   319        /*!
   320         *  ======== MAIR2 ========
   321         *  Memory attribute 2
   322         *
   323         *  Default is memory with non-gathering, reordering and early write
   324         *  acknowledegement property.
   325         */
   326        config UInt8 MAIR2 = 0x08;
   327    
   328        /*!
   329         *  ======== MAIR3 ========
   330         *  Memory attribute 3
   331         *
   332         *  Default is memory with gathering, reordering and early write
   333         *  acknowledegement property.
   334         */
   335        config UInt8 MAIR3 = 0x0C;
   336    
   337        /*!
   338         *  ======== MAIR4 ========
   339         *  Memory attribute 4
   340         *
   341         *  Default is normal inner & outer non-cacheable memory.
   342         */
   343        config UInt8 MAIR4 = 0x44;
   344    
   345        /*!
   346         *  ======== MAIR5 ========
   347         *  Memory attribute 5
   348         *
   349         *  Default is normal outer non-cacheable, inner write-back cacheable
   350         *  non-transient memory.
   351         */
   352        config UInt8 MAIR5 = 0x4F;
   353    
   354        /*!
   355         *  ======== MAIR6 ========
   356         *  Memory attribute 6
   357         *
   358         *  Default is normal outer & inner write-through cacheable non-transient
   359         *  memory.
   360         */
   361        config UInt8 MAIR6 = 0xBB;
   362    
   363        /*!
   364         *  ======== MAIR7 ========
   365         *  Memory attribute 7
   366         *
   367         *  Default is normal outer and inner write-back cacheable non-transient
   368         *  memory.
   369         */
   370        config UInt8 MAIR7 = 0x7D;
   371    
   372        /*!
   373         *  ======== initFunc ========
   374         *  MMU init function pointer
   375         *
   376         *  This config param is initialized to point to an init function that
   377         *  will perform MMU configuration using the {@link #map} runtime APIs
   378         *  provided by this module. The init function is called before
   379         *  C initialization i.e. before the data section is initialized.
   380         *  Therefore, care must be taken to not rely on any initialized
   381         *  data variables.
   382         *
   383         *  By default, the {@link #initFuncDefault Mmu_initFuncDefault} function
   384         *  designed for use with AM65x devices is used if the application doesn't
   385         *  provide its own implementation.
   386         */
   387        config InitFuncPtr initFunc = initFuncDefault;
   388    
   389        /*!
   390         *  ======== tableMemory ========
   391         *  Memory segment in which to place Mmu tables
   392         *
   393         *  If set to a non-empty string, this config param identifies the memory
   394         *  segment in which the Mmu tables are placed.
   395         *
   396         *  To prevent placement of the Mmu tables altogether, set to empty
   397         *  string "".
   398         */
   399        config String tableMemory = "DDR";
   400    
   401        /*!
   402         *  ======== tableMemory_NS ========
   403         *  Memory segment in which to place Mmu tables
   404         *
   405         *  If set to a non-empty string, this config param identifies the memory
   406         *  segment in which the Mmu tables are placed.
   407         *
   408         *  To prevent placement of the Mmu tables altogether, set to empty
   409         *  string "".
   410         */
   411        config String tableMemory_NS = "MSMC";
   412    
   413        /*!
   414         *  ======== tableArraySection ========
   415         *  Contains a table array and some state variables.
   416         *  This section is uninitialized.
   417         *
   418         *  Note: Memory containing the table array must be marked as inner &
   419         *  and outer shareable, and inner and outer write-back write-allocate
   420         *  cacheable.
   421         */
   422        metaonly config String tableArraySection =
   423            ".data.ti_sysbios_family_c7x_Mmu_tableArray";
   424    
   425        /*!
   426         *  ======== tableArraySection_NS ========
   427         *  Contains a table array and some state variables.
   428         *  This section is uninitialized.
   429         *
   430         *  Note: Memory containing the table array must be marked as inner &
   431         *  and outer shareable, and inner and outer write-back write-allocate
   432         *  cacheable.
   433         */
   434        metaonly config String tableArraySection_NS =
   435            ".data.ti_sysbios_family_c7x_Mmu_tableArray_NS";
   436    
   437        /*!
   438         *  ======== tableArrayLen ========
   439         *  Length of array of MMU tables
   440         *
   441         *  MMU module allocates memory for MMU table from a table array.
   442         *  This config param controls number of MMU tables supported.
   443         *  Each table in the array is the size of the MMU table and aligned
   444         *  to the table's size.
   445         *
   446         *  @a(Note)
   447         *  MMU table size is same as translation granule size (see
   448         *  {@link #granuleSize})
   449         */
   450        config UInt tableArrayLen = 16;
   451    
   452        /*!
   453         *  ======== enable ========
   454         *  Enables the MMU.
   455         *
   456         *  If the MMU is already enabled, then simply return.
   457         *  Otherwise this function does the following:
   458         *  @p(blist)
   459         *  If the L1 program cache is enabled, invalidate all of L1
   460         *  program cache.
   461         *  @p
   462         *
   463         *  This function enables the MMU on the core it is called from.
   464         *
   465         *  @a(Note)
   466         *  This function does not change the L1 data/program cache settings.
   467         */
   468        Void enable();
   469    
   470        /*!
   471         *  ======== initMapAttrs() ========
   472         *  Initializes the map attribute structure
   473         *
   474         *  @param(attrs)      Pointer to map attribute struct
   475         */
   476        Void initMapAttrs(MapAttrs *descAttrs);
   477    
   478        /*!
   479         *  ======== isEnabled ========
   480         *  Determines if the MMU is enabled
   481         */
   482        Bool isEnabled();
   483    
   484        /*!
   485         *  ======== map ========
   486         *  Add a mapping to MMU table
   487         *
   488         *  This API adds a mapping for the given virtual and physical
   489         *  address to the MMU table and sets the memory attributes
   490         *  as per the attributes passed to the function.
   491         *
   492         *  This API internally disables interrupts before updating the
   493         *  MMU table. The interrupts may be disabled for a long period
   494         *  of time. It is therefore recommended to either call this
   495         *  API in the Mmu.initFunc or in main().
   496         *
   497         *  The smallest mapping size (page size) supported is determined
   498         *  by the {@link #granuleSize}. The largess mapping size supported
   499         *  is 2^{@link #PA_MAX_WIDTH}-1.
   500         *
   501         *  @param(vaddr)         Virtual address (aligned to {@link #granuleSize})
   502         *  @param(paddr)         Physical address (aligned to {@link #granuleSize})
   503         *  @param(size)          Region size (aligned to {@link #granuleSize})
   504         *  @param(attrs)         Memory region attributes
   505         *  @b(returns)           Status (True-success, False-failed)
   506         */
   507        Bool map(UInt64 vaddr, UInt64 paddr, SizeT size, MapAttrs *attrs, Bool secure);
   508    
   509        /*!
   510         *  ======== setMAIR ========
   511         *  Sets the memory attribute encoding in the MAIRn register.
   512         *
   513         *  MAIR provides the memory attribute encodings to the possible
   514         *  {@link #DescriptorAttrs attrIndx} values in a long-descriptor format
   515         *  translation table entry for stage 1 translations.
   516         *
   517         *  {@link #DescriptorAttrs attrIndx}[2:0] selects the ATTRn bit-field in
   518         *  the MAIR register.
   519         *
   520         *  Memory Attribute Indirection Register (MAIR) bit assignments:
   521         *  @p(code)
   522         *         --------------------------------------------------------------
   523         *        |63     |    56|55     |     48|47     |     40|39     |     32|
   524         *         --------------------------------------------------------------
   525         *  MAIR  |     ATTR7    |     ATTR6     |     ATTR5     |     ATTR4     |
   526         *         --------------------------------------------------------------
   527         *        |31     |    24|23     |     16|15     |      8|7      |      0|
   528         *         --------------------------------------------------------------
   529         *  MAIR  |     ATTR3    |     ATTR2     |     ATTR1     |     ATTR0     |
   530         *         --------------------------------------------------------------
   531         *  @p
   532         *
   533         *  SYS/BIOS has 8 MAIR config params (MAIR0, MAIR2, ...) that are
   534         *  initialized to default value. In order to have a custom memory
   535         *  attribute, a user can either change the MAIRn config param in
   536         *  the application's cfg script or call this runtime API.
   537         *
   538         *  For more details on MAIR encodings please refer
   539         *  {@link https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile v8A ARM Architecture Reference Manual}
   540         *
   541         *  @param(attrIndx)     Memory attribute index
   542         *  @param(attr)         Memory attribute encoding
   543         *
   544         *  @a(Note)
   545         *  This function only invalidates the TLB and does not flush the cache.
   546         *  If the cacheability attribute of a region of memory is changed by
   547         *  modifying the MAIR entry for the region, the application needs to
   548         *  flush and invalidate the region of memory from the cache.
   549         */
   550        Void setMAIR(UInt8 attrIndx, UInt8 attr);
   551    
   552        /*!
   553         *  @_nodoc
   554         *  ======== startup ========
   555         *  startup function to initialize MMU module
   556         */
   557        Void startup();
   558    
   559        /*!
   560         *  ======== tlbInvAll ========
   561         *  Invalidate entire TLB (both data and instruction)
   562         */
   563        Void tlbInvAll(UInt64 type);
   564    
   565        /*!
   566         *  ======== initFuncDefault ========
   567         *  default Mmu.initFunc implementation.
   568         *
   569         *  provides Mmu regions for the AM65x's GIC, DMTimer, UART, SYSTIMER,
   570         *  and MSMC memory.
   571         */
   572        Void initFuncDefault();
   573    
   574    internal:
   575    
   576        /*
   577         *  ======== ConfigInfo ========
   578         */
   579        struct ConfigInfo {
   580            UInt64 indexMask;
   581            UInt32 tableLength;
   582            UInt8  tableOffset[4];
   583            UInt8  granuleSizeBits;
   584            UInt8  indexBits;
   585            Bool   noLevel0Table;
   586        };
   587    
   588        /*
   589         *  ======== disable ========
   590         */
   591        Void disable();
   592    
   593        /*
   594         *  ======== disableI ========
   595         */
   596        Void disableI();
   597    
   598        /*
   599         *  ======== enableI ========
   600         */
   601        Void enableI();
   602    
   603        /*
   604         *  ======== enableI_secure ========
   605         */
   606        Void enableI_secure();
   607    
   608        /*
   609         *  ======== configInfo ========
   610         *  This is a const object that contains pre-initialized config info
   611         *  about the MMU. Goal is to save some computation time at runtime
   612         *  for config info that can be pre-computed.
   613         */
   614        config ConfigInfo configInfo;
   615    
   616        /*
   617         *  ======== addBlockEntry ========
   618         */
   619        Void addBlockEntry(UInt8 level, UInt64 *tablePtr, UInt16 tableIdx,
   620            UInt64 paddr, MapAttrs *attrs);
   621    
   622        /*
   623         *  ======== addTableEntry ========
   624         */
   625        UInt64* addTableEntry(UInt64 *tablePtr, UInt16 tableIdx, MapAttrs *attrs, Bool secure);
   626    
   627        /*
   628         *  ======== allocTable ========
   629         */
   630        UInt64* allocTable(Bool secure);
   631    
   632        /*
   633         *  ======== freeTable ========
   634         */
   635        Void freeTable(UInt64 *table);
   636    
   637        /*
   638         *  ======== init ========
   639         */
   640        Void init(Ptr tableAddr, Bool secure);
   641    
   642        /*
   643         *  ======== readBlockEntry ========
   644         */
   645        Void readBlockEntry(UInt8 level, UInt64 *tablePtr, UInt16 tableIdx,
   646            UInt64 *paddr, MapAttrs *attrs);
   647    
   648        /*
   649         *  ======== setMAIRAsm ========
   650         */
   651        Void setMAIRAsm(UInt8 attrIndx, UInt8 attr);
   652    
   653        /*
   654         *  ======== tableWalk ========
   655         */
   656        Bool tableWalk(UInt8 level, UInt64 *tablePtr, UInt64 *vaddr, UInt64 *paddr,
   657            SizeT *size, MapAttrs *attrs, Bool secure);
   658    
   659        /*
   660         *  ======== setTCR ========
   661         */
   662        Void setTCR(UInt64 regVal, Bool secure);
   663    
   664        /*! Module state */
   665        struct Module_State {
   666        }
   667    }