📄 user_mmu.c
字号:
/*************************************************************************//* *//* FILE NAME VERSION *//* *//* user_mmu.c PLUS/MPC860/D 1.3 *//* *//* COMPONENT *//* *//* MMU Initialization *//* *//* DESCRIPTION *//* *//* This file contains initialization and setup routines for *//* the MMU. *//* *//* AUTHOR *//* *//* Barry Sellew, Accelerated Technology, Inc. *//* *//* DATA STRUCTURES *//* *//* MemoryRegion *//* *//* FUNCTIONS *//* *//* MMU_Init *//* *//* DEPENDENCIES *//* *//* None *//* *//* HISTORY *//* *//* NAME DATE REMARKS *//* *//* B. Sellew 04-30-1997 Initial version 1.0, adapted *//* from source code provided by *//* Motorola *//* B. Sellew 08-10-1997 Created and verified version 1.2 *//* B. Sellew 02-02-1998 Created and verified version 1.3 *//* *//*************************************************************************//* 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#ifndef NET#pragma section CPM_BUF ".bufdata" ".bufdata" #endif/* 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 */ DATA, 0x00380000, 0x00380000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH, DATA, 0x00384000, 0x00384000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH, DATA, 0x00388000, 0x00388000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,#ifdef ADS /* Map 16K BCSR registers starting at address 0x02100000 (data MMU) */ DATA, 0xf0000000, 0xf0000000, _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#ifdef EST /* Map 512K SRAM starting at address 0x04000000 (data MMU) */ DATA, 0x04000000, 0x04000000, _512K, NON_GUARDED, READ_WRITE, CACHEABLE, WRITE_BACK, /* Map 512K SRAM starting at address 0x04000000 (instruction MMU) */ INSTRUCTION, 0x04000000, 0x04000000, _512K, NON_GUARDED, EXECUTABLE, CACHEABLE, WRITE_BACK, /* Map 32K internal memory map starting at address 0xff000000 (data MMU) */ DATA, 0xff000000, 0xff000000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH, DATA, 0xff004000, 0xff004000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,#endif#ifdef MBX /* Map 32K internal memory map starting at address 0xfa200000 (data MMU) */ DATA, 0xfa200000, 0xfa200000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH, DATA, 0xfa204000, 0xfa204000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH, /* Map 16K board control registersaddress 0xfa100000 (data MMU) */ DATA, 0xfa100000, 0xfa100000, _16K, GUARDED, READ_WRITE, CACHE_INHIBIT, WRITE_THROUGH,#endif 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 */ Enable_MMU();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -