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

📄 mmush7750lib.c

📁 vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* reset mmu (SV=1 TI=1 AT=1)     *     * XXX - We needed a way to customize the MMUCR init value to reserve some     * TLB entries for SH7751 virtual PCI mapping.  It is desirable to get     * this value as an argument but here we import excMmuCrVal to keep the     * function prototype of mmuSh7750LibInit().  Now the excMmuCrVal is 0 in     * excArchLib, or it is modified if BSP called excPciMmuInit(). You might     * want to own excMmuCrVal in mmuSh7750Lib and export it to excArchLib,     * but then a bunch of MMU stuff is pulled into Boot ROM! (23oct01:hk)     */    mmuCrSet (excMmuCrVal != 0 ? excMmuCrVal : 0x00000104);    /* if the user has not specified a memory partition to obtain pages      * from (by initializing mmuPageSource), then initialize mmuPageSource     * to the system memory partition.     */    if (mmuPageSource == NULL)	mmuPageSource = memSysPartId;    /* initialize the data objects that are shared with vmLib.c */    mmuStateTransArray = &mmuStateTransArrayLocal [0];    mmuStateTransArraySize =		sizeof(mmuStateTransArrayLocal) / sizeof(STATE_TRANS_TUPLE);    mmuLibFuncs = mmuLibFuncsLocal;    mmuPageBlockSize = PAGE_BLOCK_SIZE;    if (pageSize != 4096)	{	errno = S_mmuLib_INVALID_PAGE_SIZE;	return ERROR;	}    mmuPageSize = pageSize;    /* build a dummy translation table which will hold the pte's for     * global memory.  All real translation tables will point to this     * one for controling the state of the global virtual memory.     */    lstInit (&mmuGlobalTransTbl.memFreePageList);    mmuGlobalTransTbl.memBlocksUsedArray =	calloc (MMU_BLOCKS_USED_SIZE, sizeof(void *));		/* 64 x 4 */    if (mmuGlobalTransTbl.memBlocksUsedArray == NULL)	return ERROR;    mmuGlobalTransTbl.memBlocksUsedIndex = 0;    mmuGlobalTransTbl.memBlocksUsedSize  = MMU_BLOCKS_USED_SIZE;    /* allocate a page to hold the upper level descriptor array */    mmuGlobalTransTbl.vUpperTbl = v_page = 	(PTE *)mmuPageAlloc (&mmuGlobalTransTbl);    if (v_page == NULL)	return ERROR;    for (i = 0; i < UPPER_TBL_SIZE; i++)	v_page[i].pte.td.asint = -1;	/* invalidate all descriptors */    /* write back the upper level table onto physical memory */    cacheClear (DATA_CACHE, v_page, UPPER_TBL_SIZE * sizeof(PTE));    return OK;    }/******************************************************************************** mmuTransTblCreate - create a new translation table.** create a translation table.  Allocates space for the MMU_TRANS_TBL* data structure and calls mmuTransTblInit on that object.  ** RETURNS: address of new object or NULL if allocation failed,*          or NULL if initialization failed.*/LOCAL MMU_TRANS_TBL *mmuTransTblCreate ()    {    MMU_TRANS_TBL *transTbl = (MMU_TRANS_TBL *)malloc (sizeof(MMU_TRANS_TBL));    if (transTbl == NULL)	return NULL;    if (mmuTransTblInit (transTbl) == ERROR)	{	free ((char *)transTbl);	return NULL;	}    return transTbl;    }/******************************************************************************** mmuTransTblInit - initialize a new translation table ** Initialize a new translation table.  The upper level is copied from the* global translation mmuGlobalTransTbl, so that we will share the global* virtual memory with all other translation tables.** NOTE: This routine is called from mmuTransTblCreate() only.* * RETURNS: OK or ERROR if unable to allocate memory for upper level.*/LOCAL STATUS mmuTransTblInit     (    MMU_TRANS_TBL *transTbl    )    {    PTE *v_page;		/* virtual address of upper page table */    lstInit (&transTbl->memFreePageList);    transTbl->memBlocksUsedArray = calloc (MMU_BLOCKS_USED_SIZE,sizeof(void *));    if (transTbl->memBlocksUsedArray == NULL)	return ERROR;    transTbl->memBlocksUsedIndex = 0;    transTbl->memBlocksUsedSize  = MMU_BLOCKS_USED_SIZE;    /* allocate a page to hold the upper level descriptor array */    transTbl->vUpperTbl = v_page = (PTE *)mmuPageAlloc (transTbl);    if (v_page == NULL)	return ERROR;    /* copy the upperlevel table from mmuGlobalTransTbl,     * so we get the global virtual memory      */    bcopy ((char *)mmuGlobalTransTbl.vUpperTbl, (char *)v_page, mmuPageSize);    /* write back the upper table onto physical memory */    cacheClear (DATA_CACHE, v_page, mmuPageSize);    /* write protect virtual memory pointing to the the upper level table in      * the global translation table to insure that it can't be corrupted      */    mmuStateSet (&mmuGlobalTransTbl, (void *)v_page, 		 MMU_STATE_MASK_WRITABLE | MMU_STATE_MASK_CACHEABLE,		 MMU_STATE_WRITABLE_NOT  | MMU_STATE_CACHEABLE_NOT);    return OK;    }/******************************************************************************** mmuTransTblDelete - delete a translation table.* * mmuTransTblDelete deallocates all the memory used to store the translation* table entries.  It does not deallocate physical pages mapped into the* virtual memory space.** RETURNS: OK*/LOCAL STATUS mmuTransTblDelete     (    MMU_TRANS_TBL *transTbl    )    {    int i;    /* write enable the physical page containing the upper level pte */    mmuStateSet (&mmuGlobalTransTbl, transTbl->vUpperTbl, 		 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    /* free all the blocks of pages in memBlocksUsedArray */    for (i = 0; i < transTbl->memBlocksUsedIndex; i++)	free (transTbl->memBlocksUsedArray[i]);    free (transTbl->memBlocksUsedArray);    /* free the translation table data structure */    free (transTbl);    return OK;    }/******************************************************************************** mmuVirtualPageCreate - set up translation tables for a virtual page** simply check if there's already a lower level ptel array that has a* pte for the given virtual page.  If there isn't, create one.** RETURNS OK or ERROR if couldn't allocate space for lower level ptel array.*/LOCAL STATUS mmuVirtualPageCreate     (    MMU_TRANS_TBL *transTbl,    void *v_addr			/* virtual addr to create */    )    {    PTE *vUpperPte;    PTE *v_page;    PTE *dummy;    UINT i;    if (mmuPteGet (transTbl, v_addr, &dummy) == OK)	return OK;    v_page = (PTE *)mmuPageAlloc (transTbl);		/* virtual address */    if (v_page == NULL)	return ERROR;    /* invalidate every page in the new page block */    for (i = 0; i < LOWER_TBL_SIZE; i++)	{	v_page[i].pte.l.bits              = 0;#if (CPU==SH7700)	v_page[i].pte.l.fields.ppn        = -1;	v_page[i].pte.l.fields.valid      = 0;	v_page[i].pte.l.fields.protection = 0; 	v_page[i].pte.l.fields.size       = 1; /* 4k bytes page */	v_page[i].pte.l.fields.cachable   = 0; 	v_page[i].pte.l.fields.dirty      = 1;	v_page[i].pte.l.fields.share      = 0;#elif (CPU==SH7750)	v_page[i].pte.l.fields.ppn        = -1;	v_page[i].pte.l.fields.valid      = 0;	v_page[i].pte.l.fields.size1      = 0; /* 4k bytes page */	v_page[i].pte.l.fields.protection = 0; 	v_page[i].pte.l.fields.size2      = 1; /* 4k bytes page */	v_page[i].pte.l.fields.cachable   = 0; 	v_page[i].pte.l.fields.dirty      = 1;	v_page[i].pte.l.fields.share      = 0;	v_page[i].pte.l.fields.wt         = 0;#endif	}    /* write back the lower level table onto physical memory */    cacheClear (DATA_CACHE, v_page, LOWER_TBL_SIZE * sizeof(PTE));    /* write protect the new physical page containing the pte's     * for this new page block     */    mmuStateSet (&mmuGlobalTransTbl, v_page,    		 MMU_STATE_MASK_WRITABLE | MMU_STATE_MASK_CACHEABLE,		 MMU_STATE_WRITABLE_NOT  | MMU_STATE_CACHEABLE_NOT);     /* unlock the physical page containing the upper level pte,     * so we can modify it     */    mmuStateSet (&mmuGlobalTransTbl, transTbl->vUpperTbl,                 MMU_STATE_MASK_WRITABLE, MMU_STATE_WRITABLE);    vUpperPte = &transTbl->vUpperTbl [(UINT)v_addr / PAGE_BLOCK_SIZE];    /* modify the upperLevel pte to point to the new lowerLevel pte */    vUpperPte->pte.td.adrs	= (PAGE_DESC *)(((UINT32)v_page & SH7750_PHYS_MASK) | mmuTransTblSpace);    /* write back the upperLevel pte onto physical memory */    cacheClear (DATA_CACHE, vUpperPte, sizeof(PTE));    /* write protect the upper level pte table */    mmuStateSet (&mmuGlobalTransTbl, transTbl->vUpperTbl,                 MMU_STATE_MASK_WRITABLE | MMU_STATE_MASK_CACHEABLE,		 MMU_STATE_WRITABLE_NOT  | MMU_STATE_CACHEABLE_NOT);    mmuTLBFlush (v_addr);    return OK;    }/******************************************************************************** mmuEnable - turn mmu on or off* */LOCAL STATUS mmuEnable    (    BOOL enable    )    {    int key = intLock ();	/* LOCK INTERRUPTS */    mmuOn (enable);    intUnlock (key);		/* UNLOCK INTERRUPTS */    return OK;    }/******************************************************************************** mmuStateGet - get state of virtual memory page** mmuStateGet is used to retrieve 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	 notcachable/cachable* MMU_STATE_CACHEABLE_WRITETHROUGH		 write through(SH7750)** these are or'ed together in the returned state.  Additionally, masks* are provided so that specific states may be extracted from the returned state:** MMU_STATE_MASK_VALID * MMU_STATE_MASK_WRITABLE* MMU_STATE_MASK_CACHEABLE** RETURNS: OK or ERROR if virtual page does not exist.*/LOCAL STATUS mmuStateGet     (    MMU_TRANS_TBL *transTbl,    void *v_addr,		/* page whose state we're querying */    UINT *state			/* place to return state value */    )    {    PTE *pPhys;    if (mmuPteGet (transTbl, v_addr, &pPhys) != OK)	return ERROR;    *state = pPhys->pte.l.bits;     return OK;    }/******************************************************************************** mmuStateSet - set state of virtual memory page** 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	 notcachable/cachable* MMU_STATE_CACHEABLE_WRITETHROUGH	       	 write through (SH7750)** these may be or'ed 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_CACHEABLE** These may be or'ed 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,    void *v_addr,		/* virtual page whose state to modify */     UINT stateMask,		/* mask of which state bits to modify */    UINT state			/* new state bit values */    )    {    int key;    PTE *pPte;			/* physical address of PTE on memory */    if (mmuPteGet (transTbl, v_addr, &pPte) != OK)	return ERROR;    /* modify the pte with mmu turned off and interrupts locked out */    key = intLock ();    mmuATTRSet (pPte, stateMask, state, v_addr);    intUnlock (key);    return OK;    }/******************************************************************************** mmuPageMap - map physical memory page to virtual memory page** The physical page address is entered into the pte 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 mmuPageMap     (

⌨️ 快捷键说明

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