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

📄 mmu.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        pMMU->pVmaHiArena =	RA_Create (	pRAState,
                       					"mmu vma hi",
                       					MMU_HI_ARENA_BASE, uMmuHiArenaSize, DEV_PAGE_SIZE,
                       					IMG_NULL, IMG_NULL, IMG_NULL);
        if (pMMU->pVmaHiArena==IMG_NULL) 
        {
        	PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
	    	RA_Delete (pMMU->pVmaArena);
	        _FreePageTables (pMMU);
	        HostFreeMem (PVRSRV_HOST_PAGEABLE_HEAP, pMMU);
	        return IMG_NULL;
        }
    }

    bRes = MMUFLUSH_Create (pMMU, &(pMMU->pFlush), pPager);
    if (!bRes)
    {
    	PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to MMUFLUSH_Create failed"));
    	if (pMMU->pVmaHiArena)
    		RA_Delete (pMMU->pVmaHiArena);
    	RA_Delete (pMMU->pVmaArena);
	    _FreePageTables (pMMU);
	    HostFreeMem (PVRSRV_HOST_PAGEABLE_HEAP, pMMU);
    	return IMG_NULL;
    }
    
    return pMMU;
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_Delete

    PURPOSE:    Delete an MMU device.

    PARAMETERS: In:  pMMU - The MMU to delete.
    RETURNS:
</function>
-----------------------------------------------------------------------------*/
void
MMU_Delete (MMU *pMMU)
{
    if (pMMU != IMG_NULL)
    {
        PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete ()"));
        MMUFLUSH_Delete (pMMU, &(pMMU->pFlush), pMMU->pPager);
        RA_Delete (pMMU->pVmaHiArena);
        RA_Delete (pMMU->pVmaArena);
        _FreePageTables (pMMU);
        HostFreeMem (PVRSRV_HOST_PAGEABLE_HEAP, pMMU);
    }
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_Alloc
    PURPOSE:    Allocate space in an mmu's virtual address space.
    PARAMETERS:	In:  pMMU - MMU to allocate on.
                In:  uSize - Size in bytes to allocate.
                Out: pActualSize - If non null receives actual size allocated. 
                In:  uFlags - Allocation flags.
                In:  uDevVAddrAlignment - Required alignment.
                Out: DevVAddr - Receives base address of allocation.
    RETURNS:	IMG_TRUE - Success
                IMG_FALSE - Failure
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
MMU_Alloc (MMU *pMMU,
           IMG_SIZE_T uSize,
           IMG_SIZE_T *pActualSize,
           IMG_UINT32 uFlags,
           IMG_UINT32 uDevVAddrAlignment,
           IMG_DEV_VIRTADDR *DevVAddr)
{
    RA_ARENA *pArena;

    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_Alloc (uSize=0x%x, flags=0x%x, align=0x%x)",
	      uSize, uFlags, uDevVAddrAlignment));
    
    if ((uFlags & BP_HI_MEMORY) && (MMU_HI_ARENA_SIZE>0))
        pArena = pMMU->pVmaHiArena;
    else
        pArena = pMMU->pVmaArena;

    return RA_Alloc (pArena, uSize, pActualSize, IMG_NULL, 0,
                     uDevVAddrAlignment, 0, &(DevVAddr->uiAddr));
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_Free
    PURPOSE:    Free space in an mmu's virtual address space.
    PARAMETERS:	In:  pMMU - MMU to deallocate on.
                In:  DevVAddr - Base address to deallocate.
    RETURNS:	None
</function>
-----------------------------------------------------------------------------*/
void
MMU_Free (MMU *pMMU, IMG_DEV_VIRTADDR DevVAddr)
{
    PVR_ASSERT (pMMU != IMG_NULL);

    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_Free (mmu=0x%x, dev_vaddr=0x%lx)", pMMU, DevVAddr.uiAddr));

    if (MMU_HI_ARENA_SIZE!=0 && DevVAddr.uiAddr>=MMU_HI_ARENA_BASE)
        RA_Free (pMMU->pVmaHiArena, DevVAddr.uiAddr, IMG_NULL);
    else
        RA_Free (pMMU->pVmaArena, DevVAddr.uiAddr, IMG_NULL);
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_Enable

    PURPOSE:    Enable an mmu. Establishes pages tables and takes the mmu out
                of bypass and waits for the mmu to acknowledge enabled.

    PARAMETERS: In:  pMMU - the mmu
    RETURNS:    None
</function>
-----------------------------------------------------------------------------*/
void
MMU_Enable (MMU *pMMU)
{
    IMG_UINT32 uStatus;
    
    PVR_ASSERT (pMMU != IMG_NULL);
    PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Enable ()"));

    uStatus = HW_ReadReg (pMMU->pDev, MBX1_GLOBREG_MMU_ENABLE);
    if ((uStatus & MMU_ENABLE_MASK) == MMU_ENABLE_MASK)
    {
        PVR_DPF ((PVR_DBG_MESSAGE,
		  "MMU: MMU is *ALREADY* enabled! <<<<<<<<<<<<<<<<<"));
    }
    
    HW_ModifyReg (pMMU->pDev, MBX1_GLOBREG_MMU_ENABLE, MMU_ENABLE_MASK, 0);
    DisableSpinWait (pMMU->pDev);
    HW_ModifyReg (pMMU->pDev, MBX1_GLOBREG_MMU_ENABLE, MMU_ENABLE_MASK, 1);
    /* spin, on the status port */
    _EnableSpinWait (pMMU->pDev);
    pMMU->bEnabled = IMG_TRUE;
    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_Enable ()  XXXXX MMU IS NOW ENABLED XXXXX"));
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_Disable

    PURPOSE:    Disable an mmu, takes the mmu into bypass.

    PARAMETERS: In:  pMMU - the mmu
    RETURNS:    None
</function>
-----------------------------------------------------------------------------*/
void
MMU_Disable (MMU *pMMU)
{
    PVR_ASSERT (pMMU != IMG_NULL);
    PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Disable ()"));
    HW_ModifyReg (pMMU->pDev, MBX1_GLOBREG_MMU_ENABLE, MMU_ENABLE_MASK, 0);
    DisableSpinWait (pMMU->pDev);
    pMMU->bEnabled = IMG_FALSE;
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_MapPages

    PURPOSE:    Create a linear mapping for a ranege of pages at a specified
                virtual address.
                        
    PARAMETERS: In:  pMMU - the mmu.
                In:  dev_vaddr - the device virtual address.
                In:  dev_paddr - the device physical address of the page to
                     map.
                In:  uSize - size of memory range in bytes
    RETURNS:    None
</function>
-----------------------------------------------------------------------------*/
void
MMU_MapPages (MMU *pMMU,
              IMG_DEV_VIRTADDR DevVAddr,
              IMG_DEV_PHYADDR DevPAddr,
              IMG_SIZE_T uSize)
{
    IMG_UINT32 uCount;
    
    PVR_ASSERT (pMMU != IMG_NULL);
    
    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_MapPages (mmu=0x%x,devVAddr=0x%x,devPAddr=0x%x,size=0x%x)",
	      pMMU, DevVAddr.uiAddr, DevPAddr.uiAddr, uSize));

    for (uCount=0; uCount<uSize; uCount+=DEV_PAGE_SIZE)
    {
        MMU_MapPage (pMMU, DevVAddr, DevPAddr);
        DevVAddr.uiAddr += DEV_PAGE_SIZE;
        DevPAddr.uiAddr += DEV_PAGE_SIZE;
    }
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_MapPage

    PURPOSE:    Create a mapping for one page at a specified virtual address.

    PARAMETERS: In:  pMMU - the mmu.
                In:  DevVAddr - the device virtual address.
                In:  DevPAddr - the device physical address of the page to map.
    RETURNS:    None
</function>
-----------------------------------------------------------------------------*/
void
MMU_MapPage (MMU *pMMU,
             IMG_DEV_VIRTADDR DevVAddr,
             IMG_DEV_PHYADDR DevPAddr)
{
    volatile IMG_UINTPTR_T *pt;

    PVR_ASSERT (pMMU != IMG_NULL);
#if 0
    /* This trace generates *alot* of output, hence normally it's turned off */
    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_MapPage (dv=0x%lx, dp=0x%lx)  ptr=%d pte=%d pt=0x%x",
	      DevVAddr, DevPAddr.uiAddr,
	      ptr_offset (DevVAddr),
	      pte_offset (DevVAddr),
	      pMMU->page_table[ptr_offset (DevVAddr)]));
#endif
    
    pt = pMMU->aPageTableCpuVAddr [ptr_offset (DevVAddr)];
    pt [pte_offset (DevVAddr)] = DevPAddr.uiAddr;

    if (pMMU->bEnabled)
    {
        /* with hardware support for tlb_reload we flush the tlb cache by
         * forcing reload of tlbs when an address is mapped
         */
        switch (pMMU->eFlushMechanism)
        {
        case FM_TLB_RELOAD:
            /* we have not been told to flush, but it is easier to do it here */
            MMUFLUSH_TLBReload (pMMU->pDev, DevVAddr, DevPAddr);
            break;
#if defined (FIX_HW_PRN_63)
        case FM_2D_FLUSH:
            /* handle flushing in the usual way, ie when we are told to flush */
            break;
#endif
        }
    }
    
#ifdef STUB
    env_notify_mmu_map (DevVAddr, DevPAddr);
#endif
}

/* todo: boilerplate */
void
MMU_FlushRange (MMU *pMMU,
                IMG_DEV_VIRTADDR DevVAddr,
                IMG_SIZE_T uSize)
{
    switch (pMMU->eFlushMechanism)
    {
    case FM_TLB_RELOAD:
        /* the cache is flushed during page mapping when using this mechanism */
        break;
#if defined (FIX_HW_PRN_63)
    case FM_2D_FLUSH:
        MMUFLUSH_Range (pMMU->pDev, DevVAddr, uSize, &(pMMU->pFlush));
        break;
#endif
    }
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_HaveHiArena

    PURPOSE:    Query if a high allocation arena is present.

    PARAMETERS: In:  pMMU - the mmu
    RETURNS:    IMG_TRUE - Present.
                IMG_FALSE - Not present.
</function>
-----------------------------------------------------------------------------*/
IMG_BOOL
MMU_HaveHiArena (MMU *pMMU)
{
    PVR_ASSERT (pMMU != IMG_NULL);
    PVR_DPF ((PVR_DBG_MESSAGE,
	      "MMU_HaveHiArena () = %d", MMU_HI_ARENA_SIZE>0));
    UNREFERENCED_PARAMETER (pMMU);

	if (MMU_HI_ARENA_SIZE > 0)
	{
    	return IMG_TRUE;
	}
	else
	{
    	return IMG_FALSE;
	}
}

/*----------------------------------------------------------------------------
<function>
    FUNCTION:   MMU_LowArenaVAddrRange

    PURPOSE:    Query the device virtual address range for the low arena.

    PARAMETERS: In:  pMMU - the mmu
    RETURNS:    size in bytes
</function>
-----------------------------------------------------------------------------*/
IMG_SIZE_T
MMU_LowArenaVAddrRange (MMU *pMMU)
{
    PVR_ASSERT (pMMU != IMG_NULL);
    return MMU_ARENA_SIZE;
}

⌨️ 快捷键说明

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