📄 mmu_user.c
字号:
/************************************************************************/
/* */
/* Copyright (c) 2001 by Accelerated Technology, Inc. */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in */
/* the subject matter of this material. All manufacturing, */
/* reproduction, use, and sales rights pertaining to this subject */
/* matter are governed by the license agreement. The recipient of */
/* this software implicitly accepts the terms of the license. */
/* */
/* */
/************************************************************************/
/************************************************************************/
/* FILE NAME VERSION */
/* */
/* mmu_user.c Nucleus PLUS\MPC8245\Diab C/C++ 1.13.1 */
/* */
/* DESCRIPTION */
/* */
/* L1 Page table control functions. Provides page table(4k) */
/* granularity for defining memory management attributes. */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* MemoryStruct */
/* */
/* FUNCTIONS */
/* */
/* MMU_TLB_Init */
/* MMU_Write_PTE */
/* MMU_Hash1 */
/* MMU_Set_SR */
/* MMU_Hash2 */
/* */
/* DEPENDENCIES */
/* mmu.s */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* T. Weller 12\19\2001 Created inital version 1.13.1 */
/************************************************************************/
#include "nucleus.h"
#include "mmu_user.h"
/* region types */
#define MMU_DATA 1
#define MMU_INSTRUCTION 2
#define MMU_END_REGIONS 0
/* WIMG */
#define MMU_WIMG_WRITE_THROUGH 0x00000008
#define MMU_WIMG_WRITE_BACK 0x00000000
#define MMU_WIMG_CACHE_INHIBIT 0x00000004
#define MMU_WIMG_MEM_COHERENCY 0x00000002
#define MMU_WIMG_GUARDED 0x00000001
/* PP */
#define MMU_PP_READWRITE 0x00000002
#define MMU_PP_NOACCESS 0x00000000
#define MMU_PP_READONLY 0x00000003
#define MMU_PP_READONLY2 0x00000001
#define MMU_4K 0x00001000
#define MMU_256MB 0x10000000
/* Segment Register Bits */
#define MMU_SR_SUPERVISOR_KEY 0x40000000
#define MMU_SR_USER_KEY 0x20000000
#define MMU_SR_NO_EXECUTE 0x10000000
/* SD1 Register */
#define MMU_SDR1_HMASK_8MB 0x00000000
#define MMU_SDR1_HMASK_16MB 0x00000001
#define MMU_SDR1_HMASK_32MB 0x00000003
#define MMU_SDR1_HMASK_64MB 0x00000007
#define MMU_SDR1_HMASK_128MB 0x0000000F
#define MMU_SDR1_HMASK_256MB 0x0000001F
#define MMU_SDR1_HMASK_512MB 0x0000003F
#define MMU_SDR1_HMASK_1GB 0x0000007F
#define MMU_SDR1_HMASK_2GB 0x000000FF
#define MMU_SDR1_HMASK_4GB 0x000001FF
#define MMU_VSID_HASH_MASK 0x0007FFFF
#define MMU_PAGE_INDEX_MASK 0x0FFFF000
#define MMU_NUM_TLBS 64
/* User defines */
/* This define should be changed to match the SDR1 register */
/* definition that is the closest to your total memory region */
/* defined in mem_region[] */
#define MMU_SDR1_HMASK MMU_SDR1_HMASK_16MB
/* Page Table Start address - be careful that other memory regions */
/* do not collide with the page table */
#define MMU_PT_START 0x00500000
/* Page Table Entry */
/* First word : 0 Entry valid, 1:24 VSID, 25 Hash function ID, */
/* 26:31 Abbreviated page index */
/* Second word: 0:19 RPN physical page number, 20:22 reserved. */
/* 23 referenced bit, 24 changed bit, */
/* 25:28 WIMG memory/cache control bits, */
/* 29 reserved, 30:31 PP page protection bits */
typedef struct MemoryRegion
{
UINT32 type;
UINT32 virt;
UINT32 real;
UINT32 size;
UINT32 wimg;
UINT32 pp;
} MEM_REGION;
/* The following structure defimes the memory regions that will be mapped
into the page tables.
Region type
DATA, INSTRUCTION, or END_REGIONS. If the region is set to DATA, its
entry will be placed into the data PT. If the region is set to
INSTRUCTION, its entry will be placed into the instruction PT.
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
Limited to atleast a 4k region - up to 4GB.
WIMG:
Controls the WIMG cache attributes as defined in PwerPC Programming
Environments. Sample defines are included for assigning the basic
modes.
PP:
Controls the Page protection mechanism within the L1 cache controller.
Sample defines are including for assigning the basic modes. *NOTE* The
exceptions thrown from this mechanism are _NOT_ handled and will result
in an Inst or Data access exception.
*/
MEM_REGION mem_region[] =
{
/* ram */
MMU_DATA, 0x00003000, 0x00003000, 0x00100000, MMU_WIMG_WRITE_THROUGH, MMU_PP_READWRITE,
/* Test data area */
MMU_DATA, 0x00900000, 0x00900000, 0x00100000, MMU_WIMG_WRITE_THROUGH, MMU_PP_READWRITE,
MMU_END_REGIONS, 0, 0, 0, 0, 0
};
/************************************************************************/
/* FUNCTION */
/* */
/* MMU_TLB_Init */
/* */
/* DESCRIPTION */
/* */
/* Reads the memory region table and configures the MPC740 */
/* page table accordingly */
/* */
/* CALLED BY */
/* */
/* INT_Initialize */
/* */
/* CALLS */
/* */
/* MMU_Write_PTE */
/* MMU_Hash1 */
/* MMU_Set_SR */
/* MMU_Hash2 */
/* */
/* INPUTS */
/* */
/* none */
/* */
/* OUTPUTS */
/* */
/* SUCCESS */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* D Spisak 11-03-2000 release 1.11.2 */
/* */
/************************************************************************/
int MMU_TLB_Init()
{
UINT32 total_Mem, htaborg, page_Table_Entries;
UINT32 num_Segments, effective_Address, sdr1;
UINT32 pte_Region_Count, start, rpn,sid;
int i,cnt;
UINT32 vsid; /* virtual segment ID */
UINT32 * page_Table_Start;
UINT32 tVal,tVal2,tVal3,tVal4,unused;
UINT8 permissions;
UINT8 wimg, pp, api, hash, valid;
UINT32 hash_Value_1, hash_Value_2;
UINT32 primary_PTEG, secondary_PTEG;
STATUS status;
UINT32 collisions = 0;
UINT32 collideH1, collideH2;
collideH1 = 0;
collideH2 = 0;
vsid = 0x00000000;
total_Mem = 0;
page_Table_Entries = 0;
num_Segments = 0;
effective_Address = 0;
pte_Region_Count = 0;
page_Table_Start = (UINT32 *)MMU_PT_START;
/* --validate the memory regions defined by the user-- */
i = 0;
while (mem_region[i].type != MMU_END_REGIONS)
{
/* validate the region size - must be aligned on 4k*/
if((mem_region[i].size % MMU_4K) != 0 )
{
return(-1);
}
/* validate the virtual and real start - must be aligned of 4K boundary */
if((mem_region[i].virt % MMU_4K) != 0 )
{
return(-1);
}
if((mem_region[i].real % MMU_4K) != 0 )
{
return(-1);
}
/* calculate total system memory */
total_Mem += mem_region[i].size;
i++;
}
permissions = 0x6;
/* clear all of the segment registers */
for(i = 0; i<16; i++)
{
MMU_Set_SR(i, permissions, vsid);
}
/* calculate number of segments needed */
if(total_Mem > 0)
{
num_Segments = total_Mem / MMU_256MB;
num_Segments++;
}
else
num_Segments = 0;
/* Setup the segments by going through the memory regions
It is possible for memory regions to be allocated to
the same segment - this is fine.
Memory regions must be between 4K and 256MB */
/* initialize segment registers */
i = 0;
while (mem_region[i].type != MMU_END_REGIONS)
{
/* Segment ID is the first 4 bits of the EA
This assumes virtual = real - which is a
constraint */
sid = mem_region[i].real & 0xF0000000;
vsid = mem_region[i].real & 0xF0000000;
vsid = vsid >> 24;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -