📄 user_mmu.c
字号:
/* Define memory region attribute constants */
#define _8M 0x0000000c
#define _512K 0x00000004
#define _16K 0x00000008
#define _4K 0x00000000
#define NON_GUARDED 0x00000000
#define GUARDED 0x00000010
#define READ_ONLY 0x00000c00
#define READ_WRITE 0x00000000
#define EXECUTABLE 0x00000000
#define CACHEABLE 0x00000000
#define CACHE_INHIBIT 0x00000002
#define WRITE_BACK 0x00000000
#define WRITE_THROUGH 0x00000002
#define DATA 1
#define INSTRUCTION 2
#define END_REGIONS 0
/* Define the structure that describes a user-defined memory region */
typedef struct MemoryRegion
{
unsigned type; /* Type of region -- data or instruction */
unsigned virt; /* Virtual address of memory region */
unsigned real; /* Real address of memory region */
unsigned size; /* Size of region -- 4K, 16K, 512K, or 8M */
unsigned g; /* Guarded attribute */
unsigned rwx; /* Read, write, and execute attribute */
unsigned ci; /* Cache attribute */
unsigned wt; /* Cache mode -- write-back or write-through */
} MEM_REGION;
/* The following structure defines the memory regions that will be mapped
into the translation lookaside buffers. There are two TLBs, one for
data regions and one for instruction regions. Thus memory regions for
both data and code must be defined in this structure. Each entry in the
structure defines a memory region and its attributes. The format of each
entry is as follows:
Region type, Virtual base address, Real base address, Size of region,
Guarded attribute, Read/Write attribute, Cacheing attribute, Cache mode
Region type
DATA, INSTRUCTION, or END_REGIONS. If the region is set to DATA, its
entry will be placed into the data TLB. If the region is set to
INSTRUCTION, its entry will be placed into the instruction TLB.
END_REGIONS should be used to mark the end of the list of regions.
Virtual base address
Can be any word-aligned memory address from 0-4GB.
Real base address
The physical memory address that a virtual memory access will
translate to. It must be a word-aligned memory address defined
on the hardware by the chip-select registers.
Size of region
_4K, _16K, _512K, or _8M. The memory region must be one of these
four sizes. A memory region that does not match one of these sizes
must be defined with multiple entries using combinations of these
sizes. For example, to define a 2M region, four 512K entries with
the same attributes would be defined in the structure. The only
difference between the entries would be the base addresses.
Guarded attribute
GUARDED or NON_GUARDED. If a region is set to GUARDED, instructions
or data in the region can not be accessed by out-of-order execution.
If the region is NON_GUARDED, out-of-order execution is allowed.
Read/Write attribute
READ_ONLY, READ_WRITE, or EXECUTABLE. A data region should be set to
either READ_ONLY or READ_WRITE. All instruction regions should be set
to EXECUTABLE.
Cacheing attribute
CACHEABLE or CACHE_INHIBIT. If a region is set to CACHEABLE, the
cache will be enabled for all accesses to that region. If a region
is set to CACHE_INHIBIT, all accesses will go to external memory and
bypass the cache. Any memory region that can be accessed by a
peripheral device should be set to CACHE_INHIBIT to maintain cache
coherency.
Cache mode
WRITE_BACK or WRITE_THROUGH. If a region is set to WRITE_BACK, a data
access that causes a write hit to the cache only writes to the cache,
not external memory. In the case of a write miss, the data is read
from external memory into cache and only the cache is updated. If a
region is set to WRITE_THROUGH, a data access that causes a write hit
to the cache updates both the cache and external memory. In the case
of a write miss, the data is written to external memory and the cache
is bypassed. */
/*
MEM_REGION mem_region[] =
{
// Map 3M DRAM starting at address 0x00000000 (data MMU)
DATA, 0x00000000, 0x00000000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00080000, 0x00080000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00100000, 0x00100000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00180000, 0x00180000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00200000, 0x00200000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00280000, 0x00280000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
// Map 512K DRAM starting at address 0x00000000 (instruction MMU)
INSTRUCTION, 0x00000000, 0x00000000, _512K,
NON_GUARDED, EXECUTABLE, CACHEABLE, WRITE_BACK,
// Map buffer descriptors and NET4 memory 1M total
DATA, 0x00300000, 0x00300000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x00380000, 0x00380000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
#ifdef FADS
// Map 32K BCSR registers starting at address 0x02100000 (data MMU)
DATA, 0x02100000, 0x02100000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x02104000, 0x02104000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
// Map 32K internal memory map starting at address 0x02200000 (data MMU)
DATA, 0x02200000, 0x02200000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x02204000, 0x02204000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
#endif
END_REGIONS, 0, 0, 0, 0, 0, 0, 0
};
*/
MEM_REGION mem_region[] =
{
//The flowing Map 64M~~256M SDRAM memory SPACE,
//It can use as vect, stack, ram, rtos, netmem
/* stack: org = 0x00002000, len = 0x7FE00
databss: org = 0x00080000, len = 0x200000
ram: org = 0x00280000, len = 0x1000000
rtos: org = 0x01280000, len = 0x1000000
netmem: org = 0x02280000, len = 0x1000*/
//Map 512K for vect table and stack
DATA, 0x00000000, 0x00000000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
//Map 512K for data and bss
DATA, 0x00080000, 0x00080000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00100000, 0x00100000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00180000, 0x00180000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
DATA, 0x00200000, 0x00200000, _512K,
NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK,
//Map 32M for RAM used by malloc and free function
DATA, 0x00280000, 0x00280000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x00A80000, 0x00A80000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x01280000, 0x01280000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x01A80000, 0x01A80000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
//Map 32M for RTOS memory space
DATA, 0x02280000, 0x02280000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x02A80000, 0x02A80000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x03280000, 0x03280000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x03A80000, 0x03A80000, _8M,
NON_GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
//Map 512K for vect table and stack
INSTRUCTION, 0x00000000, 0x00000000, _512K,
NON_GUARDED, EXECUTABLE, CACHE_INHIBIT, WRITE_THROUGH,
//Map 512K for data and bss
INSTRUCTION, 0x00080000, 0x00080000, _512K,
NON_GUARDED, EXECUTABLE, CACHE_INHIBIT, WRITE_THROUGH,
// Map 32K internal memory map starting at address 0x02200000 (data MMU)
DATA, 0x22000000, 0x22000000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x22004000, 0x22004000, _16K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* map 20000000 for sram or bootflah flash(2M), cs4 */
DATA, 0x20000000, 0x20000000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20080000, 0x20080000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20100000, 0x20100000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20180000, 0x20180000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* map 30200000 for dbms flash(2M), cs4 */
DATA, 0x20200000, 0x20200000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20280000, 0x20280000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20300000, 0x20300000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
DATA, 0x20380000, 0x20380000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* Map 4K for IO port(cs1) */
DATA, 0x40000000, 0x40000000, _4K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* Map 4K for dsp hpi port(cs5) */
DATA, 0x50000000, 0x50000000, _4K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* Map 4K for timer (cs6) */
DATA, 0x80000000, 0x80000000, _4K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
/* Map 512K for fpga switch (cs7) */
DATA, 0x60000000, 0x60000000, _512K,
GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,
END_REGIONS, 0, 0, 0, 0, 0, 0, 0
};
void MMU_Init();
/*************************************************************************/
/* */
/* MMU_Init */
/* */
/* This function initializes the MMU control registers and sets up the */
/* memory regions and attributes in the translation lookaside buffers. */
/* */
/*************************************************************************/
void MMU_Init()
{
int i;
int immu_index, dmmu_index;
unsigned epn, twc, rpn;
/* Clear all TLB entries */
asm(" tlbia");
/* Set Access Protection to be defined by page protection bits */
Set_MI_AP(0x04000000);
Set_MD_AP(0x04000000);
/* Setup Instruction MMU control register
- PowerPC mode
- Page resolution of protection
- Cache enabled when MMU disabled
- Do not reserve TLB entries
- Ignore Problem/Privileged state during address compare
- Initial TLB index is zero */
Set_MI_CTR(0x00000000);
/* Setup Data MMU control register
- PowerPC mode
- Page resolution of protection
- Cache enabled when MMU disabled
- Write-through mode when MMU disabled
- Do not reserve TLB entries
- TWAM set for 4k
- Ignore Problem/Privileged state during address compare
- Initial TLB index is zero */
Set_MD_CTR(0x14000000);
/* Map user-defined memory regions into TLBs */
i = 0;
immu_index = 0;
dmmu_index = 0;
while (mem_region[i].type != END_REGIONS)
{
epn = 0x00000200;
twc = 0x00000001;
rpn = 0x000001f5;
/* Set virtual memory address */
epn |= mem_region[i].virt;
/* Set level-1 attributes */
twc |= mem_region[i].g | mem_region[i].wt;
if ((mem_region[i].size == _8M) || (mem_region[i].size == _512K))
twc |= mem_region[i].size;
/* Set real memory address and level-2 attributes */
rpn |= mem_region[i].real | mem_region[i].rwx | mem_region[i].ci;
if (mem_region[i].size != _4K)
rpn |= _16K;
/* Set the TLB entry */
if (mem_region[i].type == DATA)
{
Set_D_TLB(epn, twc, rpn, dmmu_index);
dmmu_index = ++dmmu_index % 32; /* increment, wrap at 32 */
}
else
{
Set_I_TLB(epn, twc, rpn, immu_index);
immu_index = ++immu_index % 32; /* increment, wrap at 32 */
}
i++;
}
/* Enable both IMMU and DMMU */
//ATTENTION!!! Temp disable by Zhuguosheng
Enable_MMU();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -