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

📄 mmulib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    return OK;#else /* !ARM_HAS_MPU */    return ERROR;#endif /* !ARM_HAS_MPU */    } /* mmuTransTblDelete() */    #if (!ARM_HAS_MPU)/******************************************************************************** mmuVirtualPageCreate - set up translation tables for a virtual page (ARM)** Simply check if there's already a lower level page table that has a page* table entry for the given virtual page.  If there isn't, create one.** RETURNS: OK or ERROR if couldn't allocate space for lower level page table.*/LOCAL STATUS mmuVirtualPageCreate    (    MMU_TRANS_TBL * thisTbl,    /* translation table */    void *      virtPageAddr    /* virtual addr to create */    )    {    LEVEL_1_DESC *  pL1;    /* Level 1 descriptor entry */    PTE *       pPte;   /* page table entry */    /* If the virtual address already has a page table, then we've finished */    if (mmuPteGet (thisTbl, virtPageAddr, &pPte) == OK)        return OK;    /*     * The PTE doesn't exist, so create one. Allocate a "mini-heap"     * on a page aligned boundary and parcel out the 1k chunks needed by     * second level page table entries until they are exhausted. Then allocate     * and parcel the next "mini-heap". In this way, memory waste is     * significantly decreased.     */    if ( mmuSecondLevelMiniHeap == NULL         || mmuSecondLevelMiniHeap_Index >= mmuSecondLevelMiniHeap_Max )        {        mmuSecondLevelMiniHeap = (UINT8 *) memPartAlignedAlloc (mmuPageSource,                                                                mmuSecondLevelMiniHeap_Size,                                                                mmuPageSize);        if (mmuSecondLevelMiniHeap == NULL)            return ERROR;        mmuSecondLevelMiniHeap_Index = 0;        /*         * Invalidate every page table entry in the new Page Table. All will be         * fault Level 2 descriptors.         */        memset ((char *) mmuSecondLevelMiniHeap, 0, mmuSecondLevelMiniHeap_Size);        }    /*     * Assign a PTE from the mini-heap.     */    pPte = (PTE *)(mmuSecondLevelMiniHeap + (mmuSecondLevelMiniHeap_Index++ * L2_PTE_SIZE)) ;    /*     * If this pPte is on a page boundary, then set the cacheable     * state.     */    if ( ( ((int)pPte) & (mmuPageSize - 1 )) == 0)        {        /*         * mmuStateSet() will flush the cache for this page before changing         * its state         */#if (ARMMMU == ARMMMU_XSCALE)        /*         * We use the current page instead of the current pPte         */        mmuStateSet (&mmuGlobalTransTbl, pPte,                     MMU_STATE_MASK_WRITABLE | MMU_STATE_MASK_CACHEABLE | \                     MMU_STATE_MASK_EX_CACHEABLE,                     MMU_STATE_WRITABLE_NOT | MMU_STATE_CACHEABLE_NOT | \                     MMU_STATE_EX_CACHEABLE_NOT);#else        /*         * We use the current page instead of the current pPte         */        mmuStateSet (&mmuGlobalTransTbl, pPte,                     MMU_STATE_MASK_WRITABLE | MMU_STATE_MASK_CACHEABLE,                     MMU_STATE_WRITABLE_NOT | MMU_STATE_CACHEABLE_NOT);#endif        }    /*     * Unlock the physical pages containing the Level 1 Descriptor table,     * so we can modify them.     */    mmuStateSetMultiple (&mmuGlobalTransTbl, thisTbl->pLevel1Table,                         MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE,                         L1_DESC_PAGES);    pL1 = &thisTbl->pLevel1Table [(UINT) virtPageAddr/PAGE_BLOCK_SIZE];    /* modify the Level 1 Descriptor to point to the new page table */    pL1->bits = DEF_L1_PAGE;    /* Page Table descriptor, domain 0 */    pPte = _func_armVirtToPhys (pPte); /* conv Virtual to Physical Address*/    pL1->fields.addr = ((UINT) pPte) >> L1D_TO_BASE_SHIFT;    /* (Re)write-protect the Level 1 Descriptor table */    mmuStateSetMultiple (&mmuGlobalTransTbl, thisTbl->pLevel1Table,                         MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE_NOT,                         L1_DESC_PAGES);    return OK;    } /* mmuVirtualPageCreate() */    #endif (!ARM_HAS_MPU)/******************************************************************************** mmuEnable - turn MMU on or off (ARM)** SEE ALSO:* .I "ARM Architecture Reference"** RETURNS: OK*/LOCAL STATUS mmuEnable    (    BOOL    enable  /* TRUE to enable, FALSE to disable MMU */    )    {    FAST int    oldIntLev;    LOCAL BOOL  firstTime = TRUE;    /*     * We cannot unilaterally protect against FIQ as the cacheClear     * operation may take too long.     */    oldIntLev = cacheArchIntLock ();    if (enable)        {        /*         * Invalidate all TLBs. If MMU is not currently on, then we         * could be about to start using whatever has been left         * behind in them.         */#if (!ARM_HAS_MPU)        /* MPUs don't have TLBs */        mmuTLBIDFlushAll ();#endif        if (firstTime)            {#if (!ARM_HAS_MPU)            /*             * Set Access Control for domain zero to 01: client i.e.             * all accesses are checked against the Access Permissions in             * the page table entry. We only use domain zero, Access             * control for the other domains is set to 00: any access             * will cause a domain fault.             */            mmuDacrSet (0x1);#endif /* (!ARM_HAS_MPU) */            /*             * Initialize MMU Control Register. Some should have been done, in             * order to get us here at all. However, here we will set:             *             * M 1 Enable MMU             * A 0 Enable address alignment fault             * C X (D-)Cache Enable) Controlled by cacheLib             * W X (Write Buffer) Controlled by cacheLib             * P X (PROG32) should have been set before here.             * D X (DATA32) should have been set before here.             * L X (Late abort on earlier CPUs) ignore             * B X (Big/Little-endian) should have been set before here.             * S 0 (System)	} SBZ on MPUs             * R 1 (ROM)	}             * F 0 (Should be Zero)             * Z X (Branch prediction enable on 810) Controlled by cacheLib             * I X (I-cache enable) Controlled by cacheLib             */            /* set the above and any bits needed by cacheArchLib */            mmuModifyCr (MMU_ENABLE_VALUE | cacheArchState,                         MMU_ENABLE_MASK  | cacheArchState);            firstTime = FALSE;            } else    /* not first time */            mmuAEnable (cacheArchState);        /*         * Clear (flush and invalidate) the data cache (some pages may not be         * cacheable).         */        cacheClear (DATA_CACHE, 0, ENTIRE_CACHE);        /*         * cacheEnable() may have been called before this, when the MMU was off         * so set cacheDataEnabled accordingly, then call cacheFuncsSet() to         * set up the appropriate function pointers.         */        cacheDataEnabled = ((cacheArchState & MMUCR_C_ENABLE) != 0);        } else    /* disable */        {        /*         * Clear (flush and invalidate) the data cache. Leave nothing         * behind in the cache, which might either be dirty, or might         * continue to be used.         */        cacheClear (DATA_CACHE, 0, ENTIRE_CACHE);        mmuADisable ();#if (!ARM_HAS_MPU)        /* Invalidate all TLB entries: tidiness really, leave nothing behind */        mmuTLBIDFlushAll ();#endif /* (!ARM_HAS_MPU) */        cacheDataEnabled = FALSE;        }    /* Set up function pointers appropriate to actual cache enabled state */    cacheFuncsSet ();    /* Invalidate the instruction cache */    cacheInvalidate (INSTRUCTION_CACHE, 0, ENTIRE_CACHE);    mmuEnabled = enable;    intIFUnlock (oldIntLev);    return OK;    } /* mmuEnable() */    #if (!ARM_HAS_MPU)/******************************************************************************** mmuStateSet - set state of virtual memory page (ARM)** mmuStateSet is used to modify the state bits of the PTE for the given* virtual page.  The following states are provided:** 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	 cacheable/not cacheable** These may be OR'd together in the state parameter.  Additionally, masks* are provided so that only specific states may be set:** MMU_STATE_MASK_VALID* MMU_STATE_MASK_WRITABLE* MMU_STATE_MASK_CACEHABLE** These may be OR'd together in the stateMask parameter.** Accesses to a virtual page marked as invalid will result in a bus error.** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateSet    (    MMU_TRANS_TBL * transTbl,   /* translation table */    void *      pageAddr,   /* page whose state to modify */    UINT        stateMask,  /* mask of which state bits to modify */    UINT        state       /* new state bit values */    )    {    PTE *       pPte;    int oldIntLev;    if (mmuPteGet (transTbl, pageAddr, &pPte) != OK)        return ERROR;    /*     * We are about to change the state of a page. We may be about to change     * the page from cached to uncached, or mark it invalid, so we must clear     * (write out to memory and invalidate from the cache) the whole page.     */    cacheClear (DATA_CACHE, pageAddr, mmuPageSize);#if ARMCACHE_NOT_COHERENT    /* On 810, this will just do an IMB */    cacheClear (INSTRUCTION_CACHE, pageAddr, mmuPageSize);#endif    /* modify the PTE with MMU protection turned off and ints locked out */    MMU_UNLOCK (oldIntLev);    pPte->bits = (pPte->bits & ~stateMask) | (state & stateMask);    MMU_LOCK (oldIntLev);    /*     * Page entry has been updated in memory so flush the entry in the TLB     * to be sure that the TLB will be updated during the next access to this     * address.     */    mmuTLBIDFlushEntry (pageAddr);    return OK;    } /* mmuStateSet() */    #else /* ARM_HAS_MPU *//******************************************************************************** mmuDeleteRegion - delete memory region (ARM)** This routine deletes an address region definition, shuffling the* other (higher priority) regions down, if necessary, in an MPU.** The MPU must be disabled while this routine is called.** RETURNS: N/A.*/LOCAL void mmuDeleteRegion    (    MPU_REGION_REG *    regs,   /* the Protection Region Registers */    int         region  /* the region number */    )    {    int i;    UINT32 ccr, wbcr, cpr, mask1, mask2;    /*     * We already have the protection region registers. Get the cache     * control register, the write-buffer control register and the cache     * protection registers.     */    ccr =  mmuCcrGet();    wbcr = mmuWbcrGet();    cpr =  mmuPrGet();    /* shuffle the regions down from above this region */    for (i = region; i < (MPU_NUM_REGIONS - 1); i++)        regs[i].bits = regs[i+1].bits;    /* shuffle down the contents of the other registers */    mask1 = 0xFFFFFFFF << region;    mask2 = 0xFFFFFFFF << (region + 1);    ccr &= (ccr & ~mask1);    ccr |= ((ccr & mask2) >> 1);    wbcr &= (wbcr & ~mask1);    wbcr |= ((wbcr & mask2) >> 1);    mask1 = 0xFFFFFFFF << (region * 2);

⌨️ 快捷键说明

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