⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmu_user.c

📁 文件内包含了nuclues的内核代码和针对Power PC的编译器。需要用VirtNet生成一个虚拟网卡才可使用
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -