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

📄 mmulib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    mask2 = 0xFFFFFFFF << ((region + 1) * 2);    cpr &= (cpr & ~mask1);    cpr |= ((cpr & mask2) >> 1);    /* clear out the definitions for the highest numbered region */    regs[MPU_NUM_REGIONS - 1].bits = 0;    ccr &= ~(1 << (MPU_NUM_REGIONS - 1));    wbcr &= ~(1 << (MPU_NUM_REGIONS - 1));    ccr &= ~(MMU_STATE_VALID << ((MPU_NUM_REGIONS - 1) * 2));    /* put the new values into the registers */    mmuPrrSet (regs);    mmuCcrSet (ccr);    mmuWbcrSet (wbcr);    mmuPrSet (cpr);    return;    } /* mmuDeleteRegion() *//******************************************************************************** mmuStateGetRegion - get state of a memory region (ARM)** This routine extracts the state information for a region and returns* it as the "architecture-specific state".** No locking is performed during this routine. If the region* definitions are changed during the execution of this routine, an* incorrect state can be returned.** RETURNS: the (architecture-specific) state.*/LOCAL UINT32 mmuStateGetRegion    (    int region  /* the region number */    )    {    UINT32 regState;    /* Get C bit from Cache Control register */    regState = (mmuCcrGet () << (7 - region)) & MMU_STATE_CACHE_BIT;    /* Get WB bit from Write Buffer Control Register */    regState |= ((mmuWbcrGet () << (7 - region)) >> 1) & MMU_STATE_BUFFERABLE;    /* Get AP bits from Protection register */    regState |= (mmuPrGet () >> (region * 2)) & MMU_STATE_VALID;    return regState;    } /* mmuStateGetRegion() *//******************************************************************************** mmuRegionModify - modify a memory region (ARM)** This routine modifies the definition of a region.** The MPU must be disabled while this routine is called.** RETURNS: N/A.*/LOCAL void mmuRegionModify    (    MPU_REGION_REG *    regs,   /* the Protection Region Registers */    int         region, /* the region number */    UINT32      addr,   /* start address */    UINT32      size,   /* size of region */    UINT32      state,  /* (architecture-dependent) state to set */    UINT32      stateMask /* (architecture-dependent) state mask */    )    {    UINT32 val;    MMU_LOG_MSG (MMU_DEBUG_MPU,                 "regionModify: region= 0x%X, addr= 0x%X, size= 0x%X, state= 0x%X, stateMask= 0x%X\n",                 region, addr, size, state, stateMask, 0);    /* Create region definition in regs array. Mark it as active */    if (size != MMU_ENTIRE_SPACE)        regs[region].bits = (addr & MPU_REGION_BASE_MASK) | 0x01 |                            ((ffsLsb (size) - 2) << 1);    else        regs[region].bits = MPU_REGION_SIZE_MAX | 0x01;    /* write region definitions back to MPU Protection Region Registers. */    mmuPrrSet (regs);    /*     * If modifying validity, get protection register, change it     * and set it back.     */    if ((stateMask & MMU_STATE_MASK_VALID) != 0)        {        val = mmuPrGet();        val &= ~((state & MMU_STATE_VALID) << (region * 2));        val |= (state & MMU_STATE_VALID) << (region * 2);        mmuPrSet(val);        }    /* If modifying cacheable status, set cache control and WB control regs */    if ((stateMask & MMU_STATE_MASK_CACHEABLE) != 0)        {        val = mmuCcrGet();        if ((state & MMU_STATE_CACHE_BIT) != 0)            {            val |= (1 << region);            } else            {            val &= ~(1<< region);            }        mmuCcrSet (val);        val = mmuWbcrGet();        if ((state & MMU_STATE_BUFFERABLE) != 0)            {            val |= (1 << region);            } else            {            val &= ~(1<< region);            }        mmuWbcrSet (val);        }    return;    } /* mmuRegionModify() *//******************************************************************************** mmuRegionCreate - create a new memory region (ARM)** This routine creates the definition of a region.** The MPU must be disabled while this routine is called.** RETURNS: N/A.*/LOCAL STATUS mmuRegionCreate    (    MPU_REGION_REG *    regs,   /* the Protection Region Registers */    UINT32      addr,   /* start address */    UINT32      size,   /* size of region */    UINT32      state,  /* (architecture-dependent) state to set */    UINT32      stateMask /* (architecture-dependent) state mask*/    )    {    int i;    MMU_LOG_MSG (MMU_DEBUG_MPU, "regionCreate: addr = 0x%X, size = 0x%X, state=%x, stateMask=%x\n",                 addr, size, state, stateMask, 0, 0);    /* Find the first free free region, starting from the lowest priority. */    for (i = 0; i < MPU_NUM_REGIONS; i++)        {        if (regs[i].fields.enable == 0)            {            /* then region is free; modify region */            mmuRegionModify(regs, i, addr, size, state, stateMask);            break;            }        }    if (i == MPU_NUM_REGIONS)        {        /* then there was no free region */        errno = S_vmLib_NO_FREE_REGIONS;        return ERROR;        }    return OK;    }/******************************************************************************** mmuStateSetRegion - set state of memory region (ARM)** mmuStateSetRegion is used to modify the state for the given region.* The following states are provided:** MMU_STATE_VALID	MMU_STATE_VALID_NOT	 valid/invalid* 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_CACEHABLE** These may be OR'd together in the stateMask parameter.** Accesses to a region marked as invalid will result in a bus error.** RETURNS: OK or ERROR if cannot set state of or create the region.*/LOCAL STATUS mmuStateSetRegion    (    MMU_TRANS_TBL * transTbl,   /* translation table */    void *      startAddr,  /* start address of region */    UINT        stateMask,  /* mask of which state bits to modify */    UINT        state,      /* new state bit values */    UINT        size        /* size of region */    )    {#define MPU_MATCH_OTHER 1#define MPU_MATCH_SUBSET 2#define MPU_MATCH_EXACT 3    int     oldIntLev = 0;      /* keep compiler quiet */    int     i;    UINT32  regBase, regSize;    int     match = MPU_MATCH_OTHER, match2 = MPU_MATCH_OTHER;    int     region1 = -1, region2 = -1;    UINT32  addr = (UINT32) startAddr;    STATUS  ret = OK;    /*     * Obviously, if the entire address space has been specified, the     * start address should be 0!     */    if (size == MMU_ENTIRE_SPACE)        {        if (addr != 0)            {            errno = S_vmLib_NOT_PAGE_ALIGNED;            return ERROR;            }        } else        {        /* check size is an exact power of two */        if (ffsMsb(size) != ffsLsb (size))            {            errno = S_vmLib_NOT_PAGE_ALIGNED;            return ERROR;            }        /* check start address is appropriately aligned for size */        if ((addr % size) != 0)            {            errno = S_vmLib_NOT_PAGE_ALIGNED;            return ERROR;            }        }    /* modify the MPU with all interrupts locked out including FIQs */    MMU_UNLOCK (oldIntLev);    /* Get the Protection Region Registers (region address definitions) */    mmuPrrGet (transTbl->regs);    /*     * Search all current regions for an exact address match, or a     * region that is a superset of the region requested. Also look for a     * second match. Search from highest numbered (highest priority)     * region downwards.     */    for (i = (MPU_NUM_REGIONS - 1); i >= 0; i--)        {        if ((transTbl->regs[i].bits & 0x01) != 0)            {            /* region is enabled, extract start and size of region */            MMU_LOG_MSG (MMU_DEBUG_MPU, "check enabled region %d\n",                         i, 0, 0, 0, 0, 0);            regBase = transTbl->regs[i].bits & MPU_REGION_BASE_MASK;            regSize = (transTbl->regs[i].bits & MPU_REGION_SIZE_MASK) >> 1;            if (regSize == (MPU_REGION_SIZE_MAX >> 1))                regSize = MMU_ENTIRE_SPACE;            else                regSize = 1 << (regSize + 1);            if (((regBase <= addr) && ((regBase + regSize) > addr)) ||                (regSize == MMU_ENTIRE_SPACE))                {                /* address starts within this region; is this second match? */                MMU_LOG_MSG (MMU_DEBUG_MPU,                             "address 0x%X within region %X size 0x%X, regBase = 0x%X, regSize = , 0x%X\n",                             addr, i, size, regBase, regSize, 0);                if (region1 == -1)                    {                    /* not found first match yet */                    region1 = i;                    MMU_LOG_MSG (MMU_DEBUG_MPU, "setting region1 = %d\n",                                 i, 0, 0, 0, 0, 0);                    if ((regBase == addr) && (regSize == size))                        {                        match = MPU_MATCH_EXACT;                        MMU_LOG_MSG (MMU_DEBUG_MPU, "setting MATCH_EXACT\n",                                     0, 0, 0, 0, 0, 0);                        } else                        if (((regBase + regSize) >= (addr + size)) ||                            (regSize == MMU_ENTIRE_SPACE))                        {                        MMU_LOG_MSG (MMU_DEBUG_MPU,"setting MATCH_SUBSET\n",                                     0, 0, 0, 0, 0, 0);                        match = MPU_MATCH_SUBSET;                        } else                        {                        MMU_LOG_MSG (MMU_DEBUG_MPU, "setting MATCH_OTHER\n",                                     0, 0, 0, 0, 0, 0);                        match = MPU_MATCH_OTHER;                        }                    } else                    {                    if (region2 == -1)                        {                        MMU_LOG_MSG (MMU_DEBUG_MPU, "setting region2 = %d\n",                                     i, 0, 0, 0, 0, 0);                        region2 = i;                        if (((regBase == addr) && (regSize == size)) ||                            ((regBase + regSize) >= (addr + size)) ||                            (regSize == MMU_ENTIRE_SPACE))                            match2 = MPU_MATCH_SUBSET;                        else                            match2 = MPU_MATCH_OTHER;                        break;                        }                    }                } /* endif within region */            } /* endif region enabled */        } /* endfor all regions */    MMU_LOG_MSG (MMU_DEBUG_MPU,                 "end of checks, region1 = %d, region2 = %d, match=%d\n",                 region1, region2, match, 0, 0, 0);    if ((region1 != -1) && (match == MPU_MATCH_SUBSET))        {        /*         * Requested region is a subset of first matching region. If         * state matches, nothing to do, else create new region.         */        MMU_LOG_MSG (MMU_DEBUG_MPU, "subset match\n", 0, 0, 0, 0, 0, 0);        if (state != mmuStateGetRegion (region1))            {            /* state does not match existing region */            ret = mmuRegionCreate (transTbl->regs, addr, size,                                   state, stateMask);            }        } else        {        MMU_LOG_MSG (MMU_DEBUG_MPU, "else 1\n", 0, 0, 0, 0, 0, 0);        if ((region1 == -1) || (match == MPU_MATCH_OTHER))            {            /*             * Either the address start specified is not present within any             * currently defined region or the region specified overlaps a             * current region. Take simple approach and create a new region             * for the request.             */            MMU_LOG_MSG (MMU_DEBUG_MPU,                         "no match, region1 = %d, region2 = %d, match=%d\n",                         region1,

⌨️ 快捷键说明

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