module ti.sysbios.family.shared.vayu.Mmu

DSP Memory Management Unit (MMU0) Manager

This module allows the processor to map a virtual address to a different physical address and enable/disable the MMU. It does this through a translation table in memory. The translation table is 16KB and manages only the first level descriptor table. Each entry in the table defines the memory translation of a page of size 1MB (or 16MB if using supersections). [ more ... ]
C synopsis target-domain sourced in ti/sysbios/family/shared/vayu/Mmu.xdc
#include <ti/sysbios/family/shared/vayu/Mmu.h>
Functions
Void 
Void 
Void 
Void 
Bool 
Void 
Void 
Bool 
Functions common to all target modules
Typedefs
typedef enum
typedef struct
typedef enum
Constants
extern const Assert_Id 
extern const Assert_Id 
extern const Assert_Id 
extern const Mmu_Regs *
extern const Bool 
extern const UInt 
 
DETAILS
This module allows the processor to map a virtual address to a different physical address and enable/disable the MMU. It does this through a translation table in memory. The translation table is 16KB and manages only the first level descriptor table. Each entry in the table defines the memory translation of a page of size 1MB (or 16MB if using supersections).
By default, the MMU translation table is initialized with entries for every memory segment defined in the platform. Entries are also added for the peripheral addresses used by SYS/BIOS (i.e. Timers, Interrupt controller).
The translation table is placed in an output section called "ti.sysbios.family.shared.vayu.mmuTableSection". This section is placed into the platform's default dataMemory and in order to minimize object file size, specified to not be initialized via the "NOLOAD" type on GNU compilers and "NOINIT" on TI compilers.
This module does not manage the second level descriptor tables. A 'SECTION' mapped access requires only a first level fetch. In this case, there is no need for a second level descriptor table. A 'PAGE_TABLE' mapped access requires a second level descriptor table which can be supplied by the user.
The following is an example of how to place the MMU table for the address range 0x80000000-0x90000000 in the *.cfg file:
    var Mmu = xdc.useModule('ti.sysbios.family.shared.vayu.Mmu');

    // Enable the MMU
    Mmu.enableMMU = true;

    // descriptor attribute structure
    var attrs = {
        type: Mmu.FirstLevelDesc_SECTION,  // SECTION descriptor
        supersection: false
    };

    // Set the descriptor for each entry in the address range
    for (var i=0x80000000; i < 0x90000000; i = i + 0x00100000) {
        // Each 'SECTION' descriptor entry spans a 1MB address range
        Mmu.setFirstLevelDescMeta(i, i, attrs);
    }

    var memmap = Program.cpu.memoryMap;
    var DDR = null;

    // Find DDR in memory map
    for (var i=0; i < memmap.length; i++) {
        if (memmap[i].name == "DDR") {
            DDR = memmap[i];
        }
    }

    // Place the MMU table in the DDR memory segment if it exists
    if (DDR != null) {
        var sectionName = "ti.sysbios.family.shared.vayu.mmuTableSection";
        Program.sectMap[sectionName] = new Program.SectionSpec();
        Program.sectMap[sectionName].type = "NOINIT"; // NOLOAD for GNU Tools
        Program.sectMap[sectionName].loadSegment = "DDR";
    }
    else {
        print("No DDR memory segment was found");
    }

The following is an example of how to add TLB entries and lock them:
  #include <ti/sysbios/family/shared/vayu/Mmu.h>

  Int main()
  {
      Int i, j;
      Bool ret;

      // Add and lock 16 TLB entries. Once the entries are locked, they
      // cannot be evicted by the table walking logic when the MMU is enabled.
      for (i = 0x90000000, j = 0; j < 16; i+= 0x1000, j++) {
          ret = Mmu_writeTLBEntry((Ptr)i, (Ptr)i, Mmu_PageSize_SMALL);
          if (!ret) {
              // FAILED: Could not lock TLB entry. TLB is full with locked
              // entries.
              ...
          }
      }
      ...
      BIOS_start();
  }
The following is an example of how to unlock and clear TLB entries:
  #include <ti/sysbios/family/shared/vayu/Mmu.h>

  Int func()
  {
      Int i, j;

      // Unlock all TLB entries by setting locked entries base value to 0
      Mmu_setTLBLockBaseValue(0);

      // Clear (or flush) TLB entries pointed to by given virtual address.
      for (i = 0x90000000, j = 0; j < 16; i+= 0x1000, j++) {
          Mmu_clearTLBEntry((Ptr)i);
      }
      ...
  }
The following example shows how to add a second level descriptor table:
  #include <ti/sysbios/BIOS.h>
  #include <ti/sysbios/family/shared/vayu/Mmu.h>

  #define MMU_LEVEL2DESC_LARGEPAGE    0x1
  #define MMU_LEVEL2DESC_SMALLPAGE    0x2

  #pragma DATA_ALIGN(mmuL2Table, 4096);    // align to 4KB

  UInt32 mmuL2Table[256];

  Void main(Int argc, Char * argv[])
  {
      Mmu_FirstLevelDescAttrs attrs;
      Int i, j;

      // initialize the second level descriptors
      for (i = 0x80000000, j = 0; j < 256; i+= 0x1000, j++) {
          mmuL2Table[j] = (i & 0xFFFFF000) | MMU_LEVEL2DESC_SMALLPAGE;

          // For large pages use below line instead:
          // mmuL2Table[j] = (i & 0xFFFF0000) | MMU_LEVEL2DESC_LARGEPAGE;
      }

      // first level descriptor properites
      Mmu_initDescAttrs(&attrs);
      attrs.type = Mmu_FirstLevelDesc_PAGE_TABLE; // set to a page table descriptor

      // Set the first level descriptor for the virtual address 0x80000000.
      // No need to disable the MMU. The API should internally disable and
      // re-enable it.
      Mmu_setFirstLevelDesc((Ptr)0x80000000, &mmuL2Table, &attrs);

      BIOS_start();
  }

  ...
Notes:
  • There are size and alignment requirements on the second level descriptor tables depending on the page size.
  • See the SoC Reference Manual for more info.

Calling Context

Function Hwi Swi Task Main Startup
clearTLBEntry N Y Y Y Y
disable N Y Y Y Y
enable N Y Y Y Y
initDescAttrs Y Y Y Y Y
isEnabled Y Y Y Y Y
setFirstLevelDesc N Y Y Y Y
setTLBLockBaseValue N Y Y Y Y
writeTLBEntry N Y Y Y Y
Definitions:
  • Hwi: API is callable from a Hwi thread.
  • Swi: API is callable from a Swi thread.
  • Task: API is callable from a Task thread.
  • Main: API is callable during any of these phases:
    • In your module startup after this module is started (e.g. Cache_Module_startupDone() returns TRUE).
    • During xdc.runtime.Startup.lastFxns.
    • During main().
    • During BIOS.startupFxns.
  • Startup: API is callable during any of these phases:
    • During xdc.runtime.Startup.firstFxns.
    • In your module startup before this module is started (e.g. Cache_Module_startupDone() returns FALSE).
 
enum Mmu_FirstLevelDesc

First Level descriptors

C synopsis target-domain
typedef enum Mmu_FirstLevelDesc {
    Mmu_FirstLevelDesc_FAULT,
    // Virtual address is unmapped
    Mmu_FirstLevelDesc_PAGE_TABLE,
    // Page table addr descriptor
    Mmu_FirstLevelDesc_SECTION
    // Section descriptor
} Mmu_FirstLevelDesc;
 
DETAILS
Different descriptor type encodings: 0b00 -> Invalid or Fault entry 0b01 -> Page table entry 0b10 -> Section descriptor
 
enum Mmu_PageSize

Page size

C synopsis target-domain
typedef enum Mmu_PageSize {
    Mmu_PageSize_SECTION,
    // Section (1 MB)
    Mmu_PageSize_LARGE,
    // Large page (64 KB)
    Mmu_PageSize_SMALL,
    // Small page (4 KB)
    Mmu_PageSize_SUPERSECTION
    // Supersection (16 MB)
} Mmu_PageSize;
 
 
struct Mmu_FirstLevelDescAttrs

Structure for setting first level descriptor entries

C synopsis target-domain
typedef struct Mmu_FirstLevelDescAttrs {
    Mmu_FirstLevelDesc type;
    // first level descriptor type
    Bool supersection;
    // is a supersection
} Mmu_FirstLevelDescAttrs;
 
DETAILS
See the 'Memory Management Units' section of the device TRM for more details.
 
config Mmu_A_baseValueOutOfRange  // module-wide

Assert raised when TLB lock entries base value out of range

C synopsis target-domain
extern const Assert_Id Mmu_A_baseValueOutOfRange;
 
 
config Mmu_A_nullPointer  // module-wide

Assert raised when a pointer is null

C synopsis target-domain
extern const Assert_Id Mmu_A_nullPointer;
 
 
config Mmu_A_unknownDescType  // module-wide

Assert raised when the descriptor type is not recognized

C synopsis target-domain
extern const Assert_Id Mmu_A_unknownDescType;
 
 
config Mmu_baseAddr  // module-wide

MMU base address

C synopsis target-domain
extern const Mmu_Regs *Mmu_baseAddr;
 
DETAILS
If not specified, will be automatically set at runtime.
 
config Mmu_defaultAttrs  // module-wide

default descriptor attributes structure

C synopsis target-domain
extern const Mmu_FirstLevelDescAttrs Mmu_defaultAttrs;
 
 
config Mmu_enableMMU  // module-wide

Configuration parameter to enable MMU

C synopsis target-domain
extern const Bool Mmu_enableMMU;
 
 
config Mmu_numTLBEntries  // module-wide

Number of TLB Cache entries

C synopsis target-domain
extern const UInt Mmu_numTLBEntries;
 
 
Mmu_clearTLBEntry()  // module-wide

Clears (or flushes) a TLB entry

C synopsis target-domain
Void Mmu_clearTLBEntry(Ptr virtualAddr);
 
ARGUMENTS
virtualAddr — The modified virtual Address
DETAILS
This function flushes all TLB entries (including protected entries) pointed to by the given virtual address. It can be used to delete a TLB entry after it has been unlocked.
NOTE
This API internally disables and re-enables the MMU. Since the MMU hardware does not permit disabling the MMU while an interrupt is pending, this API should not be called with any interrupts still pending.
 
Mmu_disable()  // module-wide

Disables the mmu

C synopsis target-domain
Void Mmu_disable();
 
DETAILS
If the MMU is already disabled, then simply return. Otherwise this function does the following: If the L1 data cache is enabled, write back invalidate all of L1 data cache. If the L1 program cache is enabled, invalidate all of L1 program cache. This function does not change the cache L1 data/program settings. If the L2 unified cache is enabled, it is written back and invalidated. This function also disables the table walking logic and performs a global TLB flush. The global TLB flush does not affect protected TLB entries.
NOTE
The MMU hardware does not permit disabling the MMU while an interrupt is pending. If this API is called with an interrupt still pending, the MMU will generate an error.
 
Mmu_enable()  // module-wide

Enables the MMU

C synopsis target-domain
Void Mmu_enable();
 
DETAILS
If the MMU is already enabled, then simply return. Otherwise this function does the following: If the L1 program cache is enabled, invalidate all of L1 program cache. This function does not change the L1 data/program cache settings. If the L2 unified cache is enabled, it is written back and invalidated. This function also explicitly enables the table walking logic and performs a global TLB flush. The global TLB flush does not affect protected TLB entries.
 
Mmu_initDescAttrs()  // module-wide

Initializes the first level descriptor attribute structure

C synopsis target-domain
Void Mmu_initDescAttrs(Mmu_FirstLevelDescAttrs *attrs);
 
ARGUMENTS
attrs — Pointer to first level descriptor attribute struct
 
Mmu_isEnabled()  // module-wide

Determines if the MMU is enabled

C synopsis target-domain
Bool Mmu_isEnabled();
 
 
Mmu_setFirstLevelDesc()  // module-wide

Sets the descriptor for the virtual address

C synopsis target-domain
Void Mmu_setFirstLevelDesc(Ptr virtualAddr, Ptr phyAddr, Mmu_FirstLevelDescAttrs *attrs);
 
ARGUMENTS
virtualAddr — The modified virtual address
phyAddr — The physical address
attrs — Pointer to first level descriptor attribute struct
DETAILS
The first level table entry for the virtual address is mapped to the physical address with the attributes specified. The descriptor table is effective when the MMU is enabled.
NOTE
This API internally disables and re-enables the MMU. Since the MMU hardware does not permit disabling the MMU while an interrupt is pending, this API should not be called with any interrupts still pending. It is recommended to call this function from within main() before calling BIOS_start().
 
Mmu_setTLBLockBaseValue()  // module-wide

Sets the TLB locked entries base value to the given value

C synopsis target-domain
Void Mmu_setTLBLockBaseValue(UInt basevalue);
 
ARGUMENTS
basevalue — TLB locked entries base value
DETAILS
First n TLB entries (with n < total number of TLB entries) can be protected from being overwritten with new translations. n is equal to the TLB locked entries base value.
This function can be used to unlock TLB entries. Once an entry is unlocked, it can be cleared using clearTLBEntry() function.
NOTE
This API internally disables and re-enables the MMU. Since the MMU hardware does not permit disabling the MMU while an interrupt is pending, this API should not be called with any interrupts still pending.
 
Mmu_writeTLBEntry()  // module-wide

Manually adds a TLB entry and locks it

C synopsis target-domain
Bool Mmu_writeTLBEntry(Ptr virtualAddr, Ptr physicalAddr, Mmu_PageSize size);
 
ARGUMENTS
virtualAddr — The modified virtual address
phyAddr — The physical address
size — TLB page size.
RETURNS
TRUE - Entry succesfully written and locked, OR, FALSE - Write failed. No free TLB entries.
DETAILS
This function ready the TLB lock base value and uses it to select a victim TLB entry to write to. Once the new TLB entry is written, it increments the TLB lock base value to lock the entry. The TLB entries added using this function are marked as protected and therefore are not affected by global TLB flush operations.
NOTE
Due to the mechanism used to lock TLB entries, it is not possible to unlock a random locked TLB entry. All TLB entries in front need to be unlocked first. For example, if the first 4 TLB entries (i.e. TLB index 0, 1, 2 & 3) are locked and the second TLB entry (i.e. TLB index 1) needs to be unlocked, then the TLB entries with indices 1, 2 & 3 have to all be unlocked in order to unlock TLB entry with index 1. This can be done by calling setTLBLockBaseValue() function.
This API internally disables and re-enables the MMU. Since the MMU hardware does not permit disabling the MMU while an interrupt is pending, this API should not be called with any interrupts still pending. It is recommended to call this function from within main() before calling BIOS_start().
Module-Wide Built-Ins

C synopsis target-domain
Types_ModuleId Mmu_Module_id();
// Get this module's unique id
 
Bool Mmu_Module_startupDone();
// Test if this module has completed startup
 
IHeap_Handle Mmu_Module_heap();
// The heap from which this module allocates memory
 
Bool Mmu_Module_hasMask();
// Test whether this module has a diagnostics mask
 
Bits16 Mmu_Module_getMask();
// Returns the diagnostics mask for this module
 
Void Mmu_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
 
Configuration settings sourced in ti/sysbios/family/shared/vayu/Mmu.xdc
var Mmu = xdc.useModule('ti.sysbios.family.shared.vayu.Mmu');
module-wide constants & types
 
    values of type Mmu.PageSize// Page size
 
        obj.supersection// is a supersection = Bool  ...
module-wide config parameters
        msg: "A_baseValueOutOfRange: TLB lock entries base value out of range"
    };
        msg: "A_nullPointer: Pointer is null"
    };
        msg: "A_unknownDescType: Descriptor type is not recognized"
    };
        type: Mmu.FirstLevelDesc_SECTION,
        supersection: false
    };
 
module-wide functions
 
 
enum Mmu.FirstLevelDesc

First Level descriptors

Configuration settings
values of type Mmu.FirstLevelDesc
    const Mmu.FirstLevelDesc_FAULT;
    // Virtual address is unmapped
    const Mmu.FirstLevelDesc_PAGE_TABLE;
    // Page table addr descriptor
    const Mmu.FirstLevelDesc_SECTION;
    // Section descriptor
 
DETAILS
Different descriptor type encodings: 0b00 -> Invalid or Fault entry 0b01 -> Page table entry 0b10 -> Section descriptor
C SYNOPSIS
 
enum Mmu.PageSize

Page size

Configuration settings
values of type Mmu.PageSize
    const Mmu.PageSize_SECTION;
    // Section (1 MB)
    const Mmu.PageSize_LARGE;
    // Large page (64 KB)
    const Mmu.PageSize_SMALL;
    // Small page (4 KB)
    const Mmu.PageSize_SUPERSECTION;
    // Supersection (16 MB)
 
C SYNOPSIS
 
struct Mmu.FirstLevelDescAttrs

Structure for setting first level descriptor entries

Configuration settings
var obj = new Mmu.FirstLevelDescAttrs;
 
    obj.type = Mmu.FirstLevelDesc  ...
    // first level descriptor type
    obj.supersection = Bool  ...
    // is a supersection
 
DETAILS
See the 'Memory Management Units' section of the device TRM for more details.
C SYNOPSIS
 
config Mmu.A_baseValueOutOfRange  // module-wide

Assert raised when TLB lock entries base value out of range

Configuration settings
Mmu.A_baseValueOutOfRange = Assert.Desc {
    msg: "A_baseValueOutOfRange: TLB lock entries base value out of range"
};
 
C SYNOPSIS
 
config Mmu.A_nullPointer  // module-wide

Assert raised when a pointer is null

Configuration settings
Mmu.A_nullPointer = Assert.Desc {
    msg: "A_nullPointer: Pointer is null"
};
 
C SYNOPSIS
 
config Mmu.A_unknownDescType  // module-wide

Assert raised when the descriptor type is not recognized

Configuration settings
Mmu.A_unknownDescType = Assert.Desc {
    msg: "A_unknownDescType: Descriptor type is not recognized"
};
 
C SYNOPSIS
 
config Mmu.baseAddr  // module-wide

MMU base address

Configuration settings
Mmu.baseAddr = Mmu.Regs* null;
 
DETAILS
If not specified, will be automatically set at runtime.
C SYNOPSIS
 
config Mmu.defaultAttrs  // module-wide

default descriptor attributes structure

Configuration settings
Mmu.defaultAttrs = Mmu.FirstLevelDescAttrs {
    supersection: false
};
 
C SYNOPSIS
 
config Mmu.enableMMU  // module-wide

Configuration parameter to enable MMU

Configuration settings
Mmu.enableMMU = Bool false;
 
C SYNOPSIS
 
config Mmu.numTLBEntries  // module-wide

Number of TLB Cache entries

Configuration settings
Mmu.numTLBEntries = UInt 32;
 
C SYNOPSIS
 
metaonly config Mmu.common$  // module-wide

Common module configuration parameters

Configuration settings
Mmu.common$ = Types.Common$ undefined;
 
DETAILS
All modules have this configuration parameter. Its name contains the '$' character to ensure it does not conflict with configuration parameters declared by the module. This allows new configuration parameters to be added in the future without any chance of breaking existing modules.
 
metaonly config Mmu.rovViewInfo  // module-wide
Configuration settings
Mmu.rovViewInfo = ViewInfo.Instance ViewInfo.create;
 
 
metaonly Mmu.setFirstLevelDescMeta()  // module-wide

Statically sets the descriptor for the virtual address

Configuration settings
Mmu.setFirstLevelDescMeta(Ptr virtualAddr, Ptr phyAddr, Mmu.FirstLevelDescAttrs attrs) returns Void
 
ARGUMENTS
virtualAddr — The modified virtual address
phyAddr — The physical address
attrs — Pointer to first level descriptor attribute struct
DETAILS
The first level table entry for the virtual address is mapped to the physical address or points to the level 2 descriptor table. The descriptor table is effective when the MMU is enabled.
generated on Tue, 09 Oct 2018 20:57:42 GMT