📄 mmu_user.c
字号:
MMU_Set_SR(sid, permissions, vsid);
i++;
}
/* --init SDR1-- */
/* validate Page Table Origin */
if((UINT32) page_Table_Start & (UINT32)MMU_SDR1_HMASK)
{
/* Page table start address is not aligned correctly */
return(-1);
}
/* Fill out SDR1 values */
htaborg = (UINT32)page_Table_Start;
htaborg = htaborg & 0xFFFF0000;
tVal = htaborg | MMU_SDR1_HMASK;
/* Set SDR1 */
MMU_Set_SDR1(tVal);
sdr1 = tVal;
/* Clear page table */
/* Calculate number of PTEs */
page_Table_Entries = 8192;
tVal = (UINT32)page_Table_Start;
/* Loop through all of PTE's and set to invalid */
for(i = 0; i < page_Table_Entries; i++)
{
MMU_Put_UINT32((UINT32 *) tVal , 0x00000000);
MMU_Put_UINT32((UINT32 *) tVal+1, 0x00000000);
tVal=tVal+2;
}
/* Invalidate TLBs */
/* FROM MPC750UM / 5.4.3.2 - 64 tlbie's must be executed, incrementing */
/* the value in EA14-EA19 by one each time. */
for(i = 0; i < MMU_NUM_TLBS; i++)
{
/* calculate effective address */
effective_Address = i << 12;
MMU_Invalidate_TLB(effective_Address);
}
/* Build Page Table */
/* Loop through each of the memory regions */
i = 0;
while (mem_region[i].type != MMU_END_REGIONS)
{
/* Copmute number of PTEs for the region */
/* PTEs cover 4k and regions must be aligned on 4k boundaries*/
pte_Region_Count = mem_region[i].size / MMU_4K;
wimg = mem_region[i].wimg;
pp = mem_region[i].pp;
valid = 1;
/* Loop through the region's PTEs */
for(cnt = 0; cnt < pte_Region_Count; cnt++)
{
/* Calculate start address of page within mem region */
start = mem_region[i].real + (MMU_4K*cnt);
/* Encode RPN bit field */
rpn = start & 0xFFFFF000;
/* Encode API bit field */
tVal = start & 0x0FC00000; /* API is the top 6 bits
/* of the 16bit page index */
tVal = tVal >> 22; /* Shift it to a 8bit value */
api = (UINT8) tVal;
vsid = mem_region[i].real & 0xF0000000;
vsid = vsid >> 24;
/* Compute hash value 1 */
hash_Value_1 = MMU_Hash1(vsid, start);
/* Determine the PTEG address */
/* The PTEG is generated by taking the low order 13 bits of */
/* hash value 1 ORed with the high-order 16 bits of HTABORG */
/* and concatenated with six low-order 0 bits */
/* High order 7 bits */
tVal = sdr1 & 0xFE000000;
/* 7-15 */
tVal2 = ((hash_Value_1 & 0x0007FC00) >> 10) & ( sdr1 & 0x000001FF);
tVal2 = tVal2 | ((sdr1 & 0x01FF0000) >> 16);
tVal3 = hash_Value_1 & 0x000003FF;
tVal4 = tVal | (tVal2 << 16) | (tVal3 << 6);
primary_PTEG = tVal4;
hash = 0; /* This is the primary PTEG */
/* write the PTE */
status = MMU_Write_PTE(primary_PTEG, vsid, api, hash, valid, rpn, wimg, pp);
if(status != NU_TRUE)
{
/* Collision occured in PTE write */
collideH1++;
}
/* Compute hash value 2 */
hash_Value_2 = MMU_Hash2(hash_Value_1);
secondary_PTEG = ((hash_Value_2 & 0x00001FFF) << 6) | htaborg;
hash = 1; /* This is the secondary PTEG */
/* Write the PTE */
status = MMU_Write_PTE(secondary_PTEG, vsid, api, hash, valid, rpn, wimg, pp);
if(status != NU_TRUE)
{
/* Collision occured in PTE write */
collideH2++;
}
if(collideH1 && collideH2)
collisions++;
collideH1 = 0;
collideH2 = 0;
}
i++;
}
}
/************************************************************************/
/* FUNCTION */
/* */
/* MMU_Write_PTE */
/* */
/* DESCRIPTION */
/* */
/* Searches the PTEG for an open space or a secondary hash. */
/* It will clobber a secondary hash. */
/* */
/* CALLED BY */
/* */
/* MMU_Init */
/* */
/* CALLS */
/* */
/* MMU_Get_UINT32 */
/* MMU_Put_UINT32 */
/* */
/* INPUTS */
/* */
/* UINT32 pteg - address of the PTE group */
/* UINT32 vsid - VSID of PTE */
/* UINT8 api - 6bit page index */
/* UINT8 hash - encoded hash value(0=primary, 1=secondary) */
/* UINT8 valid - valid bit */
/* UINT32 rpn - real page number */
/* UINT8 wimg - WIMG memory attributes */
/* UINT8 pp - Page protection attributes */
/* */
/* OUTPUTS */
/* */
/* SUCCESS */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* D Spisak 11-03-2000 release 1.11.2 */
/* */
/************************************************************************/
STATUS MMU_Write_PTE( UINT32 pteg, UINT32 vsid, UINT8 api, UINT8 hash, UINT8 valid,
UINT32 rpn, UINT8 wimg, UINT8 pp)
{
UINT32 uPTE, lPTE, tPTE;
UINT32 * cPTE;
UINT8 i;
STATUS notWritten;
/* Make the upper and lower words of the PTE */
uPTE = (valid << 31) | ( vsid ) | ( hash << 6) | api;
lPTE = (rpn ) | (wimg << 3) | pp;
/* Given the upper and lower 32 bits of the PTE and the PTE group address */
/* Find an open spot within the PTEG and write the values */
notWritten = 1;
cPTE = (UINT32 *) pteg;
i = 0;
while(i < 8 && notWritten)
{
tPTE = MMU_Get_UINT32(cPTE);
if((tPTE & 0x80000000) && !(tPTE & 0x00000040)) /* If valid bit is set */
cPTE += 2; /* Skip this PTE */
else /* This entry is available */
{
MMU_Put_UINT32(cPTE, uPTE); /* Write the upper 32 bits */
cPTE++; /* Increment pointer */
MMU_Put_UINT32(cPTE, lPTE); /* Write the lower 32 bits */
notWritten = 0; /* We wrote it */
}
i++;
}
if(notWritten == NU_TRUE) /* The hash function failed */
return NU_FALSE; /* There were no empty spots */
return NU_TRUE; /* Hash succeeded */
}
/************************************************************************/
/* FUNCTION */
/* */
/* MMU_Hash1 */
/* */
/* DESCRIPTION */
/* */
/* Performs a page table hashing function 1 as defined by */
/* MPC750 RISC Microprocessor User's Manual */
/* */
/* */
/************************************************************************/
UINT32 MMU_Hash1(UINT32 vsid, UINT32 start)
{
UINT32 hp;
/* Mask proper bits */
vsid = vsid & MMU_VSID_HASH_MASK; /* 0x007FFFF */
/* Mask and shift page index */
start = start & MMU_PAGE_INDEX_MASK; /* 0x0FFFF000 */
start = start>>12;
/* Compute hash */
hp = vsid ^ start;
return hp;
}
/************************************************************************/
/* FUNCTION */
/* */
/* MMU_Hash2 */
/* */
/* DESCRIPTION */
/* */
/* Performs a page table hashing function 2 as defined by */
/* MPC750 RISC Microprocessor User's Manual */
/* */
/* */
/************************************************************************/
UINT32 MMU_Hash2(UINT32 hash1)
{
/* take the one's complement */
hash1 = ~hash1;
return hash1;
}
/************************************************************************/
/* FUNCTION */
/* */
/* MMU_Set_SR */
/* */
/* DESCRIPTION */
/* */
/* Configures the data for a MMU_Put_SR - write to SR register */
/* */
/* */
/************************************************************************/
void MMU_Set_SR(UINT8 index, UINT8 permissions, UINT32 vsid)
{
UINT32 out, ea;
permissions = permissions & 0x0F;
out = ((UINT32) permissions ) << 28;
out = out | vsid;
out = out & 0xF0FFFFFF; /* bits 4-7 are reserved */
index = index & 0x0F;
ea = (UINT32) index;
MMU_Put_SR(ea, out);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -