module ti.sysbios.family.arm.a8.Mmu |
|
|
|
Memory Management Unit Manager
This module allows the ARM 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 properties of memory areas of size 1MB.
These properties include memory access permissions, cacheability,
bufferability, and domain access.
[
more ... ]
#include <ti/sysbios/family/arm/a8/Mmu.h>
Functions |
Void | |
Void | |
UInt32 | |
Ptr | |
Void | |
Bool | |
Void | |
Void | |
Void | |
Functions common to all target modules |
|
|
Typedefs |
typedef enum | |
typedef struct | |
Constants |
| |
| |
| |
extern const Bool | |
DETAILS
This module allows the ARM 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 properties of memory areas of size 1MB.
These properties include memory access permissions, cacheability,
bufferability, and domain access.
By default, the MMU translation table is initialized with
cache-enabled entries for every memory segment defined in the platform.
Cache-disabled 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.arm.a8.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
and how to enable L1 data + L2 caching for the address range
0x80000000-0x90000000 in the *.cfg file:
// For Cortex-A8
var Cache = xdc.useModule('ti.sysbios.family.arm.a8.Cache');
// For Cortex-A9
var Cache = xdc.useModule('ti.sysbios.family.arm.a9.Cache');
var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
// Enable the cache
Cache.enableCache = true;
// Enable the MMU (Required for L1/L2 data caching)
Mmu.enableMMU = true;
// descriptor attribute structure for marking the memory region
// as normal cacheable memory (write-back and write-allocate)
var attrs = {
type: Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
tex: 0x1,
bufferable: true, // bufferable
cacheable: true, // cacheable
};
// 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.arm.a8.mmuTableSection";
Program.sectMap[sectionName] = new Program.SectionSpec();
Program.sectMap[sectionName].type = "NOLOAD"; // NOINIT for TI Tools
Program.sectMap[sectionName].loadSegment = "DDR";
}
else {
print("No DDR memory segment was found");
}
The following example demonstrates how to add a peripheral's address
to the MMU table so that it can be accessed by code at runtime:
// For Cortex-A8
var Cache = xdc.useModule('ti.sysbios.family.arm.a8.Cache');
// For Cortex-A9
var Cache = xdc.useModule('ti.sysbios.family.arm.a9.Cache');
var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
// Enable the cache
Cache.enableCache = true;
// Enable the MMU (Required for L1/L2 data caching)
Mmu.enableMMU = true;
// Force peripheral section to be NON cacheable strongly-ordered memory
var peripheralAttrs = {
type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
tex: 0,
bufferable : false, // bufferable
cacheable : false, // cacheable
shareable : false, // shareable
noexecute : true, // not executable
};
// Define the base address of the 1 Meg page
// the peripheral resides in.
var peripheralBaseAddr = 0xa0400000;
// Configure the corresponding MMU page descriptor accordingly
Mmu.setFirstLevelDescMeta(peripheralBaseAddr,
peripheralBaseAddr,
peripheralAttrs);
MEMORY REGION ATTRIBUTES
Memory regions can be configured as different memory types by setting
the
bufferable,
cacheable and
tex
(type extension) fields of the
FirstLevelDescAttrs structure
which is passed as an argument to
setFirstLevelDesc. The three
memory types supported by the hardware are "Normal" (cacheable), "Device"
and "Strongly-ordered" memory. "Device" and "Strongly-ordered" memory
types are recommended for mapping peripheral address space like
memory-mapped registers. These two types ensure that the memory accesses
to the peripheral memory are not performed speculatively, are not repeated
and are performed in order. The "Normal" memory type is recommended for
mapping memory regions storing application code and data.
Here are some common settings for the
bufferable,
cacheable and
tex
fields to define different memory region types:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Memory Type | bufferable | cacheable | tex +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Shareable Strongly-ordered memory | false | false | 0 +
+-----------------------------------------+------------+-----------+-----+
+ Shareable Device memory | true | false | 0 +
+-----------------------------------------+------------+-----------+-----+
+ Outer & Inner Non-cacheable | false | false | 1 +
+-----------------------------------------+------------+-----------+-----+
+ Outer & Inner Write-back Write-allocate | true | true | 1 +
+ cacheable | | | +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
For an exhaustive list of all different memory type settings and a
detailed explanation of the memory region attributes, please read the
'Short-descriptor translation table format' section of the ARM v7-AR
Architecture Reference Manual issue C.
Notes:
- The 'Supersection' table descriptor is NOT supported.
- The 'not global' page descriptor setting is NOT supported.
- The 'non-secure' page descriptor setting is NOT supported.
- There are size and alignment requirements on the second
level descriptor tables depending on the page size.
- See the ARM Architecture Reference Manual for more info.
enum Mmu_FirstLevelDesc |
|
First Level descriptors
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_RESERVED
// Reserved
} Mmu_FirstLevelDesc;
DETAILS
Different descriptor type encodings:
0b00 -> Invalid or Fault entry
0b01 -> Page table entry
0b10 -> Section descriptor
0b11 -> Reserved
struct Mmu_FirstLevelDescAttrs |
|
Structure for setting first level descriptor entries
typedef struct Mmu_FirstLevelDescAttrs {
// first level descriptor type
Bool bufferable;
// is memory section bufferable
Bool cacheable;
// is memory section cacheable
Bool shareable;
// is memory section shareable
Bool noexecute;
// is memory section not executable
UInt8 imp;
// implementation defined
UInt8 domain;
// domain access control value 0-15
UInt8 accPerm;
// access permission bits value 0-7
UInt8 tex;
// memory region attr type extension field
Bool notGlobal;
// not global bit
} Mmu_FirstLevelDescAttrs;
DETAILS
The B (Bufferable), C (Cacheable), and TEX (Type extension) bits
in the translation table descriptor define the memory region
attributes.
See the 'Short-descriptor translation table format' section of the
ARM v7-AR Architecture Reference Manual issue C for more details.
config Mmu_A_nullPointer // module-wide |
|
Assert raised when a pointer is null
config Mmu_A_unknownDescType // module-wide |
|
Assert raised when the descriptor type is not recognized
extern const Assert_Id Mmu_A_unknownDescType;
config Mmu_defaultAttrs // module-wide |
|
default descriptor attributes structure
config Mmu_enableMMU // module-wide |
|
Configuration parameter to enable MMU
extern const Bool Mmu_enableMMU;
Mmu_disable() // module-wide |
|
Disables the MMU
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.
Mmu_enable() // module-wide |
|
Enables the MMU
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.
Mmu_getDomainAccessCtrlReg() // module-wide |
|
Returns the domain access control register value (DACR)
UInt32 Mmu_getDomainAccessCtrlReg();
RETURNS
Domain Access Ctrl Register value
Mmu_getPhysicalAddr() // module-wide |
|
Returns the translated physical address for the given virtual address.
If the virtual address cannot be translated i.e. the virtual address
would generate a fault if translated, ~(0) is returned
Ptr Mmu_getPhysicalAddr(Ptr virtualAddr);
ARGUMENTS
virtualAddr
virtual address
RETURNS
translated physical address
Mmu_initDescAttrs() // module-wide |
|
Initializes the first level descriptor attribute structure
ARGUMENTS
attrs
Pointer to first level descriptor attribute struct
Mmu_isEnabled() // module-wide |
|
Determines if the MMU is enabled
Mmu_setDomainAccessCtrlReg() // module-wide |
|
Write the passed argument to domain access control register (DACR)
Void Mmu_setDomainAccessCtrlReg(UInt32 regVal);
ARGUMENTS
regVal
Contents to be written to DACR register
DETAILS
The domain access control register has 16 2-bit fields to control
the access permissions of each domain.
|31 30|29 28|27 26|25 24|23 22| ... |7 6|5 4|3 2|1 0|
-----------------------------------------------------------
Domain | D15 | D14 | D13 | D12 | D11 | ... | D3 | D2 | D1 | D0 |
-----------------------------------------------------------
Possible domain access permission value for each field:
0b00 No access. Any domain access will generate a fault.
0b01 Accesses are checked against translation table permission bits.
0b11 No access permission checking is performed for this domain.
Mmu_setFirstLevelDesc() // module-wide |
|
Sets the descriptor for the virtual address
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.
Mmu_tlbInvAll() // module-wide |
|
Invalidate entire TLB (both data and instruction)
Module-Wide Built-Ins |
|
// Get this module's unique id
Bool Mmu_Module_startupDone();
// Test if this module has completed startup
// 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
var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
module-wide constants & types
module-wide config parameters
msg: "A_nullPointer: Pointer is null"
};
msg: "A_unknownDescType: Descriptor type is not recognized"
};
bufferable: false,
cacheable: false,
shareable: false,
noexecute: false,
imp: 1,
domain: 0,
accPerm: 3,
tex: 1,
notGlobal: false
};
module-wide functions
enum Mmu.FirstLevelDesc |
|
First Level descriptors
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
const Mmu.FirstLevelDesc_RESERVED;
// Reserved
DETAILS
Different descriptor type encodings:
0b00 -> Invalid or Fault entry
0b01 -> Page table entry
0b10 -> Section descriptor
0b11 -> Reserved
C SYNOPSIS
struct Mmu.FirstLevelDescAttrs |
|
Structure for setting first level descriptor entries
var obj = new Mmu.FirstLevelDescAttrs;
// first level descriptor type
obj.bufferable = Bool ...
// is memory section bufferable
obj.cacheable = Bool ...
// is memory section cacheable
obj.shareable = Bool ...
// is memory section shareable
obj.noexecute = Bool ...
// is memory section not executable
obj.imp = UInt8 ...
// implementation defined
obj.domain = UInt8 ...
// domain access control value 0-15
obj.accPerm = UInt8 ...
// access permission bits value 0-7
obj.tex = UInt8 ...
// memory region attr type extension field
obj.notGlobal = Bool ...
// not global bit
DETAILS
The B (Bufferable), C (Cacheable), and TEX (Type extension) bits
in the translation table descriptor define the memory region
attributes.
See the 'Short-descriptor translation table format' section of the
ARM v7-AR Architecture Reference Manual issue C for more details.
C SYNOPSIS
config Mmu.A_nullPointer // module-wide |
|
Assert raised when a pointer is null
msg: "A_nullPointer: Pointer is null"
};
C SYNOPSIS
config Mmu.A_unknownDescType // module-wide |
|
Assert raised when the descriptor type is not recognized
msg: "A_unknownDescType: Descriptor type is not recognized"
};
C SYNOPSIS
config Mmu.defaultAttrs // module-wide |
|
default descriptor attributes structure
bufferable: false,
cacheable: false,
shareable: false,
noexecute: false,
imp: 1,
domain: 0,
accPerm: 3,
tex: 1,
notGlobal: false
};
C SYNOPSIS
config Mmu.enableMMU // module-wide |
|
Configuration parameter to enable MMU
Mmu.enableMMU = Bool true;
C SYNOPSIS
metaonly config Mmu.cachePlatformMemory // module-wide |
|
Flag to automatically mark platform's code/data/stack memory as
cacheable in MMU descriptor table
Mmu.cachePlatformMemory = Bool true;
DETAILS
By default, all memory regions defined in the platform an
application is built with are marked as cacheable.
If manual configuration of memory regions is required, set
this config parameter to 'false'.
SEE
metaonly config Mmu.common$ // module-wide |
|
Common module configuration parameters
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 |
|
metaonly Mmu.setFirstLevelDescMeta() // module-wide |
|
Statically sets the descriptor for the virtual address
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.
generated on Thu, 23 May 2019 00:22:45 GMT