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

📄 mmu405lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
** mmu405TransTblInit - initialize a new translation table ** Initialize a new translation table.  The level 1 table is copyed from the* global translation mmuGlobalTransTbl, so that we* will share the global virtual memory with all* other translation tables.* * RETURNS: OK or ERROR if unable to allocate memory. */LOCAL STATUS mmu405TransTblInit     (    MMU_TRANS_TBL * pNewTransTbl	/* translation table to initialize */    )    {    /* allocat memory space for a new Level 1 descriptor table */    pNewTransTbl->l1TblPtr.pL1Desc =			(LEVEL_1_DESC *) memalign (PAGE_SIZE, PAGE_SIZE);    /* if the memory cannot be allocated then return ERROR */    if (pNewTransTbl->l1TblPtr.pL1Desc == NULL)	return (ERROR);        /* copy the global level 1 descriptor table to the new table */    memcpy ((void *) pNewTransTbl->l1TblPtr.pL1Desc,			(void *) mmuGlobalTransTbl.l1TblPtr.pL1Desc, PAGE_SIZE);    /* lock the new level 1 descriptor table modification */    mmu405MemPagesWriteDisable (pNewTransTbl);    return (OK);    }/******************************************************************************** mmu405TransTblDelete - delete a translation table.* * This routine deletes a translation table.** RETURNS: OK always.*/LOCAL STATUS mmu405TransTblDelete     (    MMU_TRANS_TBL * pTransTbl		/* translation table to be deleted */    )    {    LEVEL_1_DESC 	lvl1Desc;	/* level 1 descriptor */    UINT32		ix;    /* free the PID element for this translation table */    mmu405FreePid (pTransTbl->pid);    /* free level 2 page tables */    for (ix = 0 ; ix < MMU_LVL_2_DESC_NB; ix++)	{	lvl1Desc = * (pTransTbl->l1TblPtr.pL1Desc + ix);	if (lvl1Desc.field.v)	    free ((void *) (lvl1Desc.l1desc & MMU_LVL_1_L2BA_MSK));	}         /* free the level 1 table */    free ((void *) pTransTbl->l1TblPtr.pL1Desc);    return (OK);    }/******************************************************************************** mmu405Enable - turn mmu on or off** RETURNS: OK*/LOCAL STATUS mmu405Enable     (    BOOL enable			/* TRUE to enable, FALSE to disable MMU */    )    {    int lockKey;		/* lock key for intUnlock() */    /* lock the interrupt */    lockKey = intLock ();    if (enable)	{	if (mmu405Selected & MMU_INST)	    mmuPpcAEnable (MMU_I_ADDR_TRANS);	/* enable instruction MMU */	if (mmu405Selected & MMU_DATA)	    mmuPpcAEnable (MMU_D_ADDR_TRANS);	/* enable data MMU */	}    else	{	if (mmu405Selected & MMU_INST)	    mmuPpcADisable (MMU_I_ADDR_TRANS);	/* disable instruction MMU */	if (mmu405Selected & MMU_DATA)	    mmuPpcADisable (MMU_D_ADDR_TRANS);	/* disable data MMU */	}    intUnlock (lockKey);			/* unlock the interrupt */    return (OK);    }/******************************************************************************** mmu405StateSet - set state of virtual memory page*** MMU_STATE_VALID	MMU_STATE_VALID_NOT	valid/invalid* MMU_STATE_WRITABLE	MMU_STATE_WRITABLE_NOT	writable/writeprotected* MMU_STATE_CACHEABLE	MMU_STATE_CACHEABLE_NOT	cachable/notcachable* MMU_STATE_CACHEABLE_WRITETHROUGH* MMU_STATE_CACHEABLE_COPYBACK* MMU_STATE_GUARDED	MMU_STATE_GUARDED_NOT	guarded/un-guarded** RETURNS: OK, or ERROR if descriptor address does not exist.*/LOCAL STATUS mmu405StateSet     (    MMU_TRANS_TBL *	pTransTbl, 	/* translation table */    void *		effectiveAddr,	/* page whose state to modify */     UINT 		stateMask,	/* mask of which state bits to modify */    UINT		state		/* new state bit values */    )    {    LEVEL_2_DESC *	pLvl2Desc;	/* level 2 descriptor address */    LEVEL_2_DESC	lvl2Desc;	/* level 2 descriptor */    /*      * get the level 2 descriptor address. If this descriptor address doesn't     * exist then set errno and return ERROR.     */    if (mmu405Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    /* get the Level 2 Descriptor */    lvl2Desc = *pLvl2Desc;    /*      * Check if the state to set page corresponding to <effectiveAddr> will     * not set the cache inhibited and writethrough mode. This mode is not     * supported by the cache.     */    if ((stateMask & MMU_STATE_MASK_CACHEABLE) &&	(state & MMU_STATE_CACHEABLE_NOT) &&	(state & MMU_STATE_CACHEABLE_WRITETHROUGH))	{	return (ERROR);	}    /* set or reset the VALID bit if requested */    lvl2Desc.words.word0 = (lvl2Desc.words.word0 & 				~(stateMask & MMU_STATE_MASK_VALID)) |				(state & stateMask & MMU_STATE_MASK_VALID);     /* set or reset the WIMG bit if requested */    lvl2Desc.words.word1 = (lvl2Desc.words.word1 &			~(stateMask & MMU_STATE_MASK_WIMG_WRITABLE_EXECUTE)) |		 (state & stateMask & MMU_STATE_MASK_WIMG_WRITABLE_EXECUTE);    /* update the Level 2 Descriptor */    mmu405Lvl2DescUpdate (pLvl2Desc, lvl2Desc);    /* invalidate the tlb entry for this effective address */    mmu405Tlbie (pTransTbl, effectiveAddr);    return (OK);    }/******************************************************************************** mmu405StateGet - get state of virtual memory page**/LOCAL STATUS mmu405StateGet     (    MMU_TRANS_TBL *	pTransTbl,	/* tranlation table */    void *		effectiveAddr, 	/* page whose state we're querying */    UINT *		state		/* place to return state value */    )    {    LEVEL_2_DESC *	pLvl2Desc;	/* level 2 descriptor address */    LEVEL_2_DESC	lvl2Desc;	/* level 2 descriptor */    /*      * get the level 2 descriptor address. If this descriptor address doesn't     * exist then set errno and return ERROR.     */    if (mmu405Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    /* get the Level 2 Descriptor */    lvl2Desc = *pLvl2Desc;    /* extract the state of the VALID  and WIMG bit */    * state  = lvl2Desc.words.word0 & MMU_STATE_MASK_VALID;    * state |= lvl2Desc.words.word1 & MMU_STATE_MASK_WIMG_WRITABLE_EXECUTE;    return (OK);    }/******************************************************************************** mmu405PageMap - map physical memory page to virtual memory page** The physical page address is entered into the level 2 descriptor* corresponding to the given virtual page.  The state of a newly mapped page* is undefined. ** RETURNS: OK or ERROR if translation table creation failed. */LOCAL STATUS mmu405PageMap     (    MMU_TRANS_TBL *	pTransTbl, 	/* translation table */    void *		effectiveAddr, 	/* effective address */    void *		physicalAddr	/* physical address */    )    {    LEVEL_1_DESC *	pLvl1Desc;	/* level 1 descriptor address */    LEVEL_1_DESC 	lvl1Desc;	/* level 1 descriptor */    LEVEL_2_DESC *	pLvl2Desc;	/* level 2 descriptor address */    LEVEL_2_DESC 	lvl2Desc;	/* level 2 descriptor */    UINT32		ix;		/* counter */    /* get the level 1 descriptor address */    pLvl1Desc = mmu405Lvl1DescAddrGet (pTransTbl, effectiveAddr);    /* get the level 1 descriptor */    lvl1Desc.l1desc = pLvl1Desc->l1desc;    if (!lvl1Desc.field.v)	{	/* 	 * the level 2 desciptor table is not valid (doesn't exist) then 	 * allocate a piece of memory to save the level 2 desciptor table	 * The level 2 table needs to be aligned on a 4byte boundary	 * and has a size of 1024 entries * 8 bytes/entry = 8K.	 */	pLvl2Desc = (LEVEL_2_DESC *) memalign (PAGE_SIZE, 				MMU_LVL_2_DESC_NB * sizeof(LEVEL_2_DESC));	/* 	 * check if the level 2 desciptor table was created properly. If	 * not then return ERROR.	 */	if (pLvl2Desc == NULL)	    return (ERROR);			/* 	 * invalid all level 2 descriptors by clearing the new level	 * 2 descriptor table created.	 */	lvl2Desc.field.epn = 0;		/* effective page number */	lvl2Desc.field.rsvd1 = 0;	lvl2Desc.field.size = 1;	/* default 4KB page */	lvl2Desc.field.v = 0;		/* initially invalid */	lvl2Desc.field.e = 0;		/* big endian */	lvl2Desc.field.u0 = 0;		/* no user defined attribute */	lvl2Desc.field.rsvd2 = 0;	lvl2Desc.field.rpn = 0;		/* real page number */	lvl2Desc.field.rsvd3 = 0;		lvl2Desc.field.ex = 1;		/* no execute protection */	lvl2Desc.field.wr = 0;		/* no write protection */	lvl2Desc.field.zsel = 0;	/* select zone 0 */	lvl2Desc.field.w = 0;	/* no write thru */	lvl2Desc.field.i = 0;	/* no cache inhibit */	lvl2Desc.field.m = 0;	/* memory coherent: no effect */	lvl2Desc.field.g = 0;	/* memory unguarded */	for (ix = 0; ix < MMU_LVL_2_DESC_NB; ix ++)	    pLvl2Desc[ix] = lvl2Desc;	/* 	 * set the Level 1 Descriptor with the	 * new level 2 descriptor table created.	 */	lvl1Desc.l1desc = ((UINT32) pLvl2Desc) & MMU_LVL_1_L2BA_MSK;	lvl1Desc.field.v   = 1;	/* segment valid */	/* update the Level 1 descriptor in table */	mmu405Lvl1DescUpdate (pLvl1Desc, lvl1Desc);	}    /*      * Get the level 2 descriptor address. If the level 2 descriptor doesn't     * exist then return ERROR.      */    if (mmu405Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	return (ERROR);    /* get the level 2 descriptor */    lvl2Desc = *pLvl2Desc;    /* save the real address & effective addr in the level 2 descriptors */    lvl2Desc.field.rpn = (UINT32) physicalAddr >> MMU_RPN_SHIFT;    lvl2Desc.field.epn = (UINT32) effectiveAddr >> MMU_RPN_SHIFT;    /* set the valid bit in the level 2 descriptor */    lvl2Desc.field.v = 1;    /* update the Level 2 descriptor in table */    mmu405Lvl2DescUpdate (pLvl2Desc, lvl2Desc);    /* invalidate the tlb entry for this effective addr */    mmu405Tlbie (pTransTbl, effectiveAddr);    return (OK);    }/******************************************************************************** mmu405GlobalPageMap - map physical memory page to global virtual memory page** mmuPpcGlobalPageMap is used to map physical pages into global virtual memory* that is shared by all virtual memory contexts.  The translation tables* for this section of the virtual space are shared by all virtual memory* contexts.** RETURNS: OK or ERROR if no pte for given virtual page.*/LOCAL STATUS mmu405GlobalPageMap     (    void *  effectiveAddr, 	/* effective address */    void *  physicalAddr	/* physical address */    )    {    return (mmu405PageMap (&mmuGlobalTransTbl, effectiveAddr, physicalAddr));    }/******************************************************************************** mmu405Translate - translate a virtual address to a physical address** Traverse the translation table and extract the physical address for the* given virtual address from the level 2 descriptor corresponding to the* virtual address.** RETURNS: OK or ERROR if no level 2 descriptor found for given virtual address.*/LOCAL STATUS mmu405Translate     (    MMU_TRANS_TBL *	pTransTbl,	/* translation table */    void *		effectiveAddr,	/* effective address */    void **		physicalAddr	/* where to place the result */    )    {    LEVEL_2_DESC *	pLvl2Desc;	/* Level 2 descriptor address */    EFFECTIVE_ADDR	effAddr;	/* effective address */    REAL_ADDRESS	realAddr;	/* real address */    /*      * find the level 2 descriptor corresponding to the <effectiveAddr>     * in the translation table pointed to by the <pTransTbl> structure.     * If this level 2 descriptor cannot be found then return ERROR.     */    if (mmu405Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) != OK)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    /* check if the level 2 descriptor found is valid. If not return ERROR */    if (!pLvl2Desc->field.v)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    effAddr = * ((EFFECTIVE_ADDR *) &effectiveAddr);    /* build the real address */    realAddr.field.rpn = pLvl2Desc->field.rpn;    realAddr.field.po  = effAddr.field.po;    * physicalAddr = realAddr.realAddr;    return (OK);    }/******************************************************************************** mmu405CurrentSet - change active translation table** This function changes the virtual memory context by loading the PID* register with the PID value saved in the translation* table structure pointed to by <pTransTbl>.** RETURNS: N/A**/void mmu405CurrentSet     (

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -