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

📄 mmu800lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
*/LOCAL STATUS mmu800TransTblInit     (    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 */    mmu800MemPagesWriteDisable (pNewTransTbl);    return (OK);    }/******************************************************************************** mmu800TransTblDelete - delete a translation table.* * This routine deletes a translation table.** RETURNS: OK always.*/LOCAL STATUS mmu800TransTblDelete     (    MMU_TRANS_TBL * pTransTbl		/* translation table to be deleted */    )    {    LEVEL_1_DESC 	lvl1Desc;	/* level 1 descriptor */    LEVEL_1_DESC 	globalLvl1Desc;	/* level 1 descriptor */    u_int		ix;    int                 key;    for (ix = 0 ; ix < MMU_LVL_2_DESC_NB; ix++)	{	/* Move through L1 descriptor table */	pTransTbl->l1TblPtr.l1index = ix;	/* Grab global version of same L1 descriptor. Careful not to allow other          * tasks access to the global descriptor table.          */	key=intLock();	mmuGlobalTransTbl.l1TblPtr.l1index=ix;	globalLvl1Desc=*mmuGlobalTransTbl.l1TblPtr.pL1Desc;        mmuGlobalTransTbl.l1TblPtr.l1index=0;	intUnlock(key);		lvl1Desc = *pTransTbl->l1TblPtr.pL1Desc;	if (lvl1Desc.v)	    {	      /*  Check to see if L2 descriptor actually created                *  in global translation table. If so do not free memory, in use.               */   	      if ((lvl1Desc.l1desc & MMU_LVL_1_L2BA_MSK) !=		  (globalLvl1Desc.l1desc & MMU_LVL_1_L2BA_MSK))	         free ((void *) (lvl1Desc.l1desc & MMU_LVL_1_L2BA_MSK));	    }	}    /* Reset index so free is done a base of L1 descriptor table */    pTransTbl->l1TblPtr.l1index = 0;    /* free the PTEG table */    free ((void *) pTransTbl->l1TblPtr.pL1Desc);    free ((void *) pTransTbl);    return (OK);    }/******************************************************************************** mmu800Enable - turn mmu on or off** RETURNS: OK*/LOCAL STATUS mmu800Enable     (    BOOL enable			/* TRUE to enable, FALSE to disable MMU */    )    {    int lockKey;		/* lock key for intUnlock() */    /* lock the interrupt */    lockKey = intLock ();    if (enable)	{	if (mmu800Selected & MMU_INST)	    mmuPpcAEnable (MMU_I_ADDR_TRANS);	/* enable instruction MMU */	if (mmu800Selected & MMU_DATA)	    mmuPpcAEnable (MMU_D_ADDR_TRANS);	/* enable data MMU */	}    else	{	if (mmu800Selected & MMU_INST)	    mmuPpcADisable (MMU_I_ADDR_TRANS);	/* disable instruction MMU */	if (mmu800Selected & MMU_DATA)	    mmuPpcADisable (MMU_D_ADDR_TRANS);	/* disable data MMU */	}    intUnlock (lockKey);			/* unlock the interrupt */    return (OK);    }/******************************************************************************** mmu800StateSet - set state of virtual memory page** Note : Exercise extreme caution when changing a page from copyback to* writethrough. The 860 architecture handles the writethrough/copyback* attribute at the 4MB Level 1 segment level, not the 4KB Level 2 page* level.  This function does not attempt to automatically flush cache* lines belonging to the entire 4MB segment. It does, however, invalidate* all TLB entries mapping any part of the 4MB segment.** The application must handle the flush implications explicitly.  In order* to change a 4MB segment from copyback to writethrough, first use* cacheFlush on the entire 4MB segment to flush any dirty cache lines,* then use mmuStateSet on the first page of the segment to change the* caching attributes from copyback to writethrough.* * 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** RETURNS: OK, or ERROR if descriptor address does not exist.*/LOCAL STATUS mmu800StateSet     (    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_1_DESC *	pLvl1Desc;	/* level 1 descriptor address */    LEVEL_1_DESC 	lvl1Desc,oldLvl1Desc;	/* level 1 descriptor */    LEVEL_2_DESC *	pLvl2Desc;	/* level 2 descriptor address */    LEVEL_2_DESC	lvl2Desc,oldLvl2Desc;	/* level 2 descriptor */    /* get the level 1 descriptor address */    pLvl1Desc = mmu800Lvl1DescAddrGet (pTransTbl, effectiveAddr);    /*      * get the level 2 descriptor address. If this descriptor address doesn't     * exist then set errno and return ERROR.     */    if (mmu800Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    /* get the Level 1 Descriptor */    lvl1Desc.l1desc = pLvl1Desc->l1desc;    oldLvl1Desc.l1desc = pLvl1Desc->l1desc;    /* get the Level 2 Descriptor */    lvl2Desc.l2desc = pLvl2Desc->l2desc;    oldLvl2Desc.l2desc = pLvl2Desc->l2desc;    /* Any change of state in the cache requires the page in question to        be flushed but not done until just before the tlb invalidate entry */    /* set the VALID bit if requested */    if (stateMask & MMU_STATE_MASK_VALID)        {        if ((state & MMU_STATE_MASK_VALID) == MMU_STATE_VALID) 	    lvl2Desc.v = 1;			/* set the Valid bit */	else	    lvl2Desc.v = 0;			/* clear the Valid bit */        }    /* set the CACHE state if requested */    if (stateMask & MMU_STATE_MASK_CACHEABLE)        {        if ((state & MMU_STATE_MASK_CACHEABLE) == MMU_STATE_CACHEABLE_NOT) 	    lvl2Desc.ci = 1;			/* set the Cache Inhibit bit */	else	    {	    lvl2Desc.ci = 0;			/* clear the Cache Inhibit bit*/	    if ((state & MMU_STATE_MASK_CACHEABLE) ==					MMU_STATE_CACHEABLE_WRITETHROUGH) 		lvl1Desc.wt = 1;		/* set the writethrough cache */	    else		lvl1Desc.wt = 0;		/* set the copyback cache */	    }        }    /* set the GUARDED bit if requested */        if (stateMask & MMU_STATE_MASK_GUARDED)        {	if ((state & MMU_STATE_MASK_GUARDED) == MMU_STATE_GUARDED) 	    lvl1Desc.g = 1;			/* set the Guarded bit */	else	    lvl1Desc.g = 0;			/* clear the Guarded bit */        }    /* set/unset the WRITABLE BIT if requested */    if (stateMask & MMU_STATE_MASK_WRITABLE)        {       	if ((state & MMU_STATE_MASK_WRITABLE) == MMU_STATE_WRITABLE) 	    lvl2Desc.pp = 2;			/* set to R/W */	else	    lvl2Desc.pp = 3;			/* set to R/O */        }    /* Flush page if cache inhibit is going to be set */    if ( (lvl2Desc.ci!=oldLvl2Desc.ci) && /* Have cache inhibit changed */	 (lvl2Desc.ci==1) && /* Is it about to be marked cache inhibit */	 (oldLvl1Desc.wt==0) && /* Only need to do this if in copyback mode */	 (oldLvl2Desc.v==1) ) /* Make sure old page is valid */        cacheArchFlush(DATA_CACHE,effectiveAddr,PAGE_SIZE);    mmu800Lvl1DescUpdate (pLvl1Desc, lvl1Desc);    mmu800Lvl2DescUpdate (pLvl2Desc, lvl2Desc);    /* Check to see if L1 descriptor has changed */    if ((lvl1Desc.g!=oldLvl1Desc.g) || (lvl1Desc.wt != oldLvl1Desc.wt))          /* L1 attribute so invalidate SEGMENT           * Quicker than invalidating each page for 4MB	  * The number of TLB misses resulting in this command is assumed           * to be inconsequential for system initialisation.          */         mmuPpcTlbInvalidateAll();      else          mmuPpcTlbie (effectiveAddr);  /* invalidate page so new descriptor is loaded */        return (OK);    }/******************************************************************************** mmu800StateGet - get state of virtual memory page**/LOCAL STATUS mmu800StateGet     (    MMU_TRANS_TBL *	pTransTbl,	/* tranlation table */    void *		effectiveAddr, 	/* page whose state we're querying */    UINT *		state		/* place to return state value */    )    {    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 */    /* get the level 1 descriptor address */    pLvl1Desc = mmu800Lvl1DescAddrGet (pTransTbl, effectiveAddr);    /*      * get the level 2 descriptor address. If this descriptor address doesn't     * exist then set errno and return ERROR.     */    if (mmu800Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	{	errno = S_mmuLib_NO_DESCRIPTOR;	return (ERROR);	}    /* get the Level 1 Descriptor */    lvl1Desc.l1desc = pLvl1Desc->l1desc;    /* get the Level 2 Descriptor */    lvl2Desc.l2desc = pLvl2Desc->l2desc;    *state=0;    /* Get the various supported MMU states */    if (lvl1Desc.wt==1) *state |= MMU_STATE_CACHEABLE_WRITETHROUGH;    if (lvl1Desc.g==1) *state |= MMU_STATE_GUARDED;    if (lvl2Desc.v==1) *state |= MMU_STATE_VALID;    if (lvl2Desc.ci==0) *state |= MMU_STATE_CACHEABLE;    if (lvl2Desc.pp==2) *state |= MMU_STATE_WRITABLE;        return (OK);    }/******************************************************************************** mmu800PageMap - 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 mmu800PageMap     (    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 */    u_int		ix;		/* counter */    /* get the level 1 descriptor address */    pLvl1Desc = mmu800Lvl1DescAddrGet (pTransTbl, effectiveAddr);    /* get the level 1 descriptor */    lvl1Desc.l1desc = pLvl1Desc->l1desc;    if (!lvl1Desc.v)	{	/* 	 * the level 2 desciptor is not valid (doesn't exit) then 	 * allocate a piece of memory to save the level 2 desciptor table	 */	pLvl2Desc = (LEVEL_2_DESC *) memalign (PAGE_SIZE, PAGE_SIZE);	/* 	 * 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.rpn = 0;		/* Real page Number */	lvl2Desc.pp  = 2;		/* Executable Read/Write page */	lvl2Desc.ppe = 0;		/* PowerPC encoding */	lvl2Desc.c   = 0;		/* Not changed page */	lvl2Desc.spv = 0xf;		/* All sub-page valid */ 	lvl2Desc.sps = 0;		/* 4 K Bytes page */	lvl2Desc.sh  = 1;		/* ASID comparaison disabled */	lvl2Desc.v   = 0;		/* Page Not Valid */	for (ix = 0; ix < MMU_LVL_2_DESC_NB; ix ++)	    pLvl2Desc[ix] = lvl2Desc;	/* 	 * set the Level 1 Descriptor with default option for the	 * new level 2 descriptor table created.	 */	lvl1Desc.l1desc = ((u_int) pLvl2Desc) & MMU_LVL_1_L2BA_MSK;	lvl1Desc.apg = 0;	/* use the Access Protection Group Number 0 */	lvl1Desc.g   = 0;	/* not guarded */	lvl1Desc.ps  = 0;	/* small page size (4k or 16k) */	lvl1Desc.wt  = 0;	/* cache copyback mode */	lvl1Desc.v   = 1;	/* segment valid */	/* update the Level 1 descriptor in table */	mmu800Lvl1DescUpdate (pLvl1Desc, lvl1Desc);	}    /*      * Get the level 2 descriptor address. If the level 2 descriptor doesn't     * exist then return ERROR.      */    if (mmu800Lvl2DescAddrGet (pTransTbl, effectiveAddr, &pLvl2Desc) == ERROR)	return (ERROR);    /* get the level 1 descriptor */    lvl2Desc.l2desc = pLvl2Desc->l2desc;    /* save the real address in the level 2 descriptors */    lvl2Desc.rpn = (u_int) physicalAddr >> MMU_RPN_SHIFT;

⌨️ 快捷键说明

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