1 /**********************************************************************
2 Copyright (c) Imagination Technologies Ltd.
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 ******************************************************************************/
25 #include "services_headers.h"
26 #include "buffer_manager.h"
30 #include "sgxapi_km.h"
32 #include "sgxinfokm.h"
34 #include "sgxconfig.h"
36 #define UINT32_MAX_VALUE 0xFFFFFFFFUL
38 #define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
40 typedef struct _MMU_PT_INFO_
43 IMG_VOID *hPTPageOSMemHandle;
44 IMG_CPU_VIRTADDR PTPageCpuVAddr;
45 IMG_UINT32 ui32ValidPTECount;
51 PVRSRV_DEVICE_NODE *psDeviceNode;
54 IMG_CPU_VIRTADDR pvPDCpuVAddr;
55 IMG_DEV_PHYADDR sPDDevPAddr;
57 IMG_VOID *hPDOSMemHandle;
60 MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES];
62 PVRSRV_SGXDEV_INFO *psDevInfo;
65 IMG_UINT32 ui32PDumpMMUContextID;
68 struct _MMU_CONTEXT_ *psNext;
74 MMU_CONTEXT *psMMUContext;
79 IMG_UINT32 ui32PDBaseIndex;
81 IMG_UINT32 ui32PageTableCount;
83 IMG_UINT32 ui32PTETotal;
85 IMG_UINT32 ui32PDEPageSizeCtrl;
90 IMG_UINT32 ui32DataPageSize;
92 IMG_UINT32 ui32DataPageBitWidth;
94 IMG_UINT32 ui32DataPageMask;
99 IMG_UINT32 ui32PTShift;
101 IMG_UINT32 ui32PTBitWidth;
103 IMG_UINT32 ui32PTMask;
105 IMG_UINT32 ui32PTSize;
107 IMG_UINT32 ui32PTECount;
112 IMG_UINT32 ui32PDShift;
114 IMG_UINT32 ui32PDBitWidth;
116 IMG_UINT32 ui32PDMask;
121 DEV_ARENA_DESCRIPTOR *psDevArena;
126 #if defined (SUPPORT_SGX_MMU_DUMMY_PAGE)
127 #define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF
132 MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
133 IMG_DEV_VIRTADDR DevVAddr,
136 IMG_HANDLE hUniqueTag);
141 static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr);
146 static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
148 IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
152 for(i = 0; i < 1024; i += 8)
154 PVR_DPF((PVR_DBG_WARNING,
155 "%.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx %.8lx\n",
156 p[i + 0], p[i + 1], p[i + 2], p[i + 3],
157 p[i + 4], p[i + 5], p[i + 6], p[i + 7]));
161 static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
163 IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr;
164 IMG_UINT32 i, ui32Count = 0;
167 for(i = 0; i < 1024; i++)
168 if(p[i] & SGX_MMU_PTE_VALID)
171 if(psPTInfoList->ui32ValidPTECount != ui32Count)
173 PVR_DPF((PVR_DBG_WARNING, "ui32ValidPTECount: %lu ui32Count: %lu\n",
174 psPTInfoList->ui32ValidPTECount, ui32Count));
175 DumpPT(psPTInfoList);
180 static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList)
182 PVR_UNREFERENCED_PARAMETER(psPTInfoList);
185 static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
187 PVR_UNREFERENCED_PARAMETER(psPTInfoList);
191 #ifdef SUPPORT_SGX_MMU_BYPASS
193 EnableHostAccess (MMU_CONTEXT *psMMUContext)
195 IMG_UINT32 ui32RegVal;
196 IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
201 ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL);
203 OSWriteHWReg(pvRegsBaseKM,
205 ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
207 PDUMPREG(EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
211 DisableHostAccess (MMU_CONTEXT *psMMUContext)
213 IMG_UINT32 ui32RegVal;
214 IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM;
220 OSWriteHWReg(pvRegsBaseKM,
222 ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK);
224 PDUMPREG(EUR_CR_BIF_CTRL, 0);
229 IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo)
231 #if defined(SGX_FEATURE_MP)
232 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL;
235 PVR_UNREFERENCED_PARAMETER(psDevInfo);
240 IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo)
242 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD;
243 #if defined(SGX_FEATURE_SYSTEM_CACHE)
244 MMU_InvalidateSystemLevelCache(psDevInfo);
249 IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
251 psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT;
252 #if defined(SGX_FEATURE_SYSTEM_CACHE)
253 MMU_InvalidateSystemLevelCache(psDevInfo);
259 _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
260 MMU_PT_INFO *psPTInfoList,
261 IMG_DEV_PHYADDR *psDevPAddr)
263 IMG_DEV_PHYADDR sDevPAddr;
264 IMG_CPU_PHYADDR sCpuPAddr;
269 if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
272 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
273 pMMUHeap->ui32PTSize,
275 (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr,
276 &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK)
278 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed"));
283 if(psPTInfoList->PTPageCpuVAddr)
285 sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr);
290 sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0);
293 sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
297 IMG_SYS_PHYADDR sSysPAddr;
303 if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena,
310 &(sSysPAddr.uiAddr))!= IMG_TRUE)
312 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed"));
317 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
319 psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
321 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
322 &psPTInfoList->hPTPageOSMemHandle);
323 if(!psPTInfoList->PTPageCpuVAddr)
325 PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables"));
330 sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
333 PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr);
337 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
339 IMG_UINT32 *pui32Tmp;
342 pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
344 for(i=0; i<pMMUHeap->ui32PTECount; i++)
346 pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
352 OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
356 PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
358 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
361 *psDevPAddr = sDevPAddr;
368 _FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
374 if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
377 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
378 pMMUHeap->ui32PTSize,
379 psPTInfoList->PTPageCpuVAddr,
380 psPTInfoList->hPTPageOSMemHandle);
384 IMG_SYS_PHYADDR sSysPAddr;
385 IMG_CPU_PHYADDR sCpuPAddr;
388 sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->PTPageCpuVAddr);
389 sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr);
393 OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr,
395 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
396 psPTInfoList->hPTPageOSMemHandle);
401 RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
408 _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT)
410 IMG_UINT32 *pui32PDEntry;
412 IMG_UINT32 ui32PDIndex;
414 MMU_PT_INFO **ppsPTInfoList;
416 SysAcquireData(&psSysData);
419 ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
422 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
426 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0)
428 DumpPT(ppsPTInfoList[ui32PTIndex]);
434 PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0);
438 PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
439 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
441 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, PDUMP_PT_UNIQUETAG);
444 switch(pMMUHeap->psDevArena->DevMemHeapType)
446 case DEVICE_MEMORY_HEAP_SHARED :
447 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
450 MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
455 pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
456 pui32PDEntry += ui32PDIndex;
458 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
460 pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
461 >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
462 | SGX_MMU_PDE_PAGE_SIZE_4K
468 pui32PDEntry[ui32PTIndex] = 0;
473 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
476 psMMUContext = psMMUContext->psNext;
480 case DEVICE_MEMORY_HEAP_PERCONTEXT :
481 case DEVICE_MEMORY_HEAP_KERNEL :
484 pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
485 pui32PDEntry += ui32PDIndex;
487 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
489 pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr
490 >>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
491 | SGX_MMU_PDE_PAGE_SIZE_4K
497 pui32PDEntry[ui32PTIndex] = 0;
502 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
507 PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"));
513 if(ppsPTInfoList[ui32PTIndex] != IMG_NULL)
515 if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL)
517 IMG_PUINT32 pui32Tmp;
519 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
523 (i<pMMUHeap->ui32PTETotal) && (i<pMMUHeap->ui32PTECount);
533 _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]);
539 pMMUHeap->ui32PTETotal -= i;
544 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
550 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
552 ppsPTInfoList[ui32PTIndex],
554 ppsPTInfoList[ui32PTIndex] = IMG_NULL;
560 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount;
563 PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
567 _DeferredFreePageTables (MMU_HEAP *pMMUHeap)
571 for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
573 _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
575 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
580 _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
582 IMG_UINT32 ui32PageTableCount;
583 IMG_UINT32 ui32PDIndex;
585 IMG_UINT32 *pui32PDEntry;
586 MMU_PT_INFO **ppsPTInfoList;
588 IMG_DEV_VIRTADDR sHighDevVAddr;
591 #if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
592 PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE));
596 SysAcquireData(&psSysData);
599 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
603 if((UINT32_MAX_VALUE - DevVAddr.uiAddr)
604 < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask))
607 sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
611 sHighDevVAddr.uiAddr = DevVAddr.uiAddr
613 + pMMUHeap->ui32DataPageMask
614 + pMMUHeap->ui32PTMask;
617 ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
619 ui32PageTableCount -= ui32PDIndex;
622 pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
623 pui32PDEntry += ui32PDIndex;
626 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
628 PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PageTableCount);
629 PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PageTableCount);
632 for(i=0; i<ui32PageTableCount; i++)
634 if(ppsPTInfoList[i] == IMG_NULL)
636 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
637 sizeof (MMU_PT_INFO),
638 (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
639 "MMU Page Table Info");
640 if (ppsPTInfoList[i] == IMG_NULL)
642 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed"));
645 OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
648 if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
649 && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
651 IMG_DEV_PHYADDR sDevPAddr;
652 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
653 IMG_UINT32 *pui32Tmp;
657 PVR_ASSERT(pui32PDEntry[i] == 0);
660 if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
662 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
666 switch(pMMUHeap->psDevArena->DevMemHeapType)
668 case DEVICE_MEMORY_HEAP_SHARED :
669 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED :
672 MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
677 pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
678 pui32PDEntry += ui32PDIndex;
681 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
682 | pMMUHeap->ui32PDEPageSizeCtrl
686 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
689 psMMUContext = psMMUContext->psNext;
693 case DEVICE_MEMORY_HEAP_PERCONTEXT :
694 case DEVICE_MEMORY_HEAP_KERNEL :
697 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
698 | pMMUHeap->ui32PDEPageSizeCtrl
702 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
707 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type"));
712 #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
717 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
723 PVR_ASSERT(pui32PDEntry[i] != 0);
727 #if defined(SGX_FEATURE_SYSTEM_CACHE)
728 MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
736 MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr)
738 IMG_UINT32 *pui32Tmp;
740 IMG_CPU_VIRTADDR pvPDCpuVAddr;
741 IMG_DEV_PHYADDR sPDDevPAddr;
742 IMG_CPU_PHYADDR sCpuPAddr;
743 MMU_CONTEXT *psMMUContext;
744 IMG_HANDLE hPDOSMemHandle;
746 PVRSRV_SGXDEV_INFO *psDevInfo;
748 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise"));
750 SysAcquireData(&psSysData);
752 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
753 sizeof (MMU_CONTEXT),
754 (IMG_VOID **)&psMMUContext, IMG_NULL,
756 if (psMMUContext == IMG_NULL)
758 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"));
759 return PVRSRV_ERROR_GENERIC;
761 OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT));
764 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
765 psMMUContext->psDevInfo = psDevInfo;
768 psMMUContext->psDeviceNode = psDeviceNode;
771 if(psDeviceNode->psLocalDevMemArena == IMG_NULL)
773 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
777 &hPDOSMemHandle) != PVRSRV_OK)
779 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
780 return PVRSRV_ERROR_GENERIC;
785 sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr);
790 sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
792 sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
795 PageTest(pvPDCpuVAddr, sPDDevPAddr);
798 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
800 if(!psDevInfo->pvMMUContextList)
803 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
806 &psDevInfo->pvDummyPTPageCpuVAddr,
807 &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK)
809 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
810 return PVRSRV_ERROR_GENERIC;
813 if(psDevInfo->pvDummyPTPageCpuVAddr)
815 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr);
820 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0);
822 psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
825 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
828 &psDevInfo->pvDummyDataPageCpuVAddr,
829 &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK)
831 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
832 return PVRSRV_ERROR_GENERIC;
835 if(psDevInfo->pvDummyDataPageCpuVAddr)
837 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr);
841 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0);
843 psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
849 IMG_SYS_PHYADDR sSysPAddr;
852 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
859 &(sSysPAddr.uiAddr))!= IMG_TRUE)
861 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
862 return PVRSRV_ERROR_GENERIC;
866 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
867 sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
868 pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr,
870 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
874 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
875 return PVRSRV_ERROR_GENERIC;
879 PageTest(pvPDCpuVAddr, sPDDevPAddr);
882 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
884 if(!psDevInfo->pvMMUContextList)
887 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
894 &(sSysPAddr.uiAddr))!= IMG_TRUE)
896 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
897 return PVRSRV_ERROR_GENERIC;
901 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
902 psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
903 psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
905 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
906 &psDevInfo->hDummyPTPageOSMemHandle);
907 if(!psDevInfo->pvDummyPTPageCpuVAddr)
909 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
910 return PVRSRV_ERROR_GENERIC;
914 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
921 &(sSysPAddr.uiAddr))!= IMG_TRUE)
923 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
924 return PVRSRV_ERROR_GENERIC;
928 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
929 psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
930 psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
932 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
933 &psDevInfo->hDummyDataPageOSMemHandle);
934 if(!psDevInfo->pvDummyDataPageCpuVAddr)
936 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
937 return PVRSRV_ERROR_GENERIC;
944 PDUMPCOMMENT("Alloc page directory");
945 #ifdef SUPPORT_SGX_MMU_BYPASS
946 EnableHostAccess(psMMUContext);
949 PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
953 pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
957 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"));
958 return PVRSRV_ERROR_GENERIC;
961 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
963 for(i=0; i<SGX_MMU_PD_SIZE; i++)
965 pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
966 | SGX_MMU_PDE_PAGE_SIZE_4K
970 if(!psDevInfo->pvMMUContextList)
975 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
976 for(i=0; i<SGX_MMU_PT_SIZE; i++)
978 pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
982 PDUMPCOMMENT("Dummy Page table contents");
983 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
987 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
988 for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
990 pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
993 PDUMPCOMMENT("Dummy Data Page contents");
994 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
998 for(i=0; i<SGX_MMU_PD_SIZE; i++)
1006 PDUMPCOMMENT("Page directory contents");
1007 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1011 if(PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX,
1013 &psMMUContext->ui32PDumpMMUContextID,
1016 pvPDCpuVAddr) != PVRSRV_OK)
1018 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed"));
1019 return PVRSRV_ERROR_GENERIC;
1024 psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
1025 psMMUContext->sPDDevPAddr = sPDDevPAddr;
1026 psMMUContext->hPDOSMemHandle = hPDOSMemHandle;
1029 *ppsMMUContext = psMMUContext;
1032 *psPDDevPAddr = sPDDevPAddr;
1035 psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
1036 psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext;
1038 #ifdef SUPPORT_SGX_MMU_BYPASS
1039 DisableHostAccess(psMMUContext);
1046 MMU_Finalise (MMU_CONTEXT *psMMUContext)
1048 IMG_UINT32 *pui32Tmp, i;
1049 SYS_DATA *psSysData;
1050 MMU_CONTEXT **ppsMMUContext;
1051 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1052 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
1053 MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
1056 SysAcquireData(&psSysData);
1059 PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, "SGXMEM", psMMUContext->ui32PDumpMMUContextID, 2);
1062 PDUMPCOMMENT("Free page directory");
1063 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1064 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1065 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1066 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
1069 pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
1072 for(i=0; i<SGX_MMU_PD_SIZE; i++)
1082 if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
1084 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1086 psMMUContext->pvPDCpuVAddr,
1087 psMMUContext->hPDOSMemHandle);
1089 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1091 if(!psMMUContextList->psNext)
1093 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1095 psDevInfo->pvDummyPTPageCpuVAddr,
1096 psDevInfo->hDummyPTPageOSMemHandle);
1097 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1099 psDevInfo->pvDummyDataPageCpuVAddr,
1100 psDevInfo->hDummyDataPageOSMemHandle);
1106 IMG_SYS_PHYADDR sSysPAddr;
1107 IMG_CPU_PHYADDR sCpuPAddr;
1110 sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->pvPDCpuVAddr);
1111 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1114 OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr,
1116 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1117 psMMUContext->hPDOSMemHandle);
1119 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1121 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1123 if(!psMMUContextList->psNext)
1126 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyPTPageCpuVAddr);
1127 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1130 OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr,
1132 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1133 psDevInfo->hDummyPTPageOSMemHandle);
1135 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1138 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->pvDummyDataPageCpuVAddr);
1139 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1142 OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr,
1144 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1145 psDevInfo->hDummyDataPageOSMemHandle);
1147 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1152 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
1155 ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList;
1156 while(*ppsMMUContext)
1158 if(*ppsMMUContext == psMMUContext)
1161 *ppsMMUContext = psMMUContext->psNext;
1166 ppsMMUContext = &((*ppsMMUContext)->psNext);
1170 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL);
1176 MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
1178 IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
1179 IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr;
1180 IMG_UINT32 ui32PDEntry;
1181 #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1182 IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
1186 pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1187 pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1192 PDUMPCOMMENT("Page directory shared heap range copy");
1193 #ifdef SUPPORT_SGX_MMU_BYPASS
1194 EnableHostAccess(psMMUContext);
1197 for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
1199 #if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1201 PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
1205 pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
1206 if (pui32PDCpuVAddr[ui32PDEntry])
1208 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1210 #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1211 bInvalidateDirectoryCache = IMG_TRUE;
1216 #ifdef SUPPORT_SGX_MMU_BYPASS
1217 DisableHostAccess(psMMUContext);
1220 #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS)
1221 if (bInvalidateDirectoryCache)
1227 MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo);
1234 MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
1235 IMG_DEV_VIRTADDR sDevVAddr,
1236 IMG_UINT32 ui32PageCount,
1237 IMG_HANDLE hUniqueTag)
1239 IMG_DEV_VIRTADDR sTmpDevVAddr;
1241 IMG_UINT32 ui32PDIndex;
1242 IMG_UINT32 ui32PTIndex;
1243 IMG_UINT32 *pui32Tmp;
1244 IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
1246 #if !defined (PDUMP)
1247 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1250 sTmpDevVAddr = sDevVAddr;
1252 for(i=0; i<ui32PageCount; i++)
1254 MMU_PT_INFO **ppsPTInfoList;
1257 ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
1260 ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
1264 ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
1267 if (!ppsPTInfoList[0])
1269 PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
1272 sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
1279 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
1287 CheckPT(ppsPTInfoList[0]);
1290 if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
1292 ppsPTInfoList[0]->ui32ValidPTECount--;
1296 PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex ));
1300 PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
1302 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1304 pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1305 | SGX_MMU_PTE_VALID;
1308 pui32Tmp[ui32PTIndex] = 0;
1311 CheckPT(ppsPTInfoList[0]);
1316 if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0)
1318 _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
1319 bInvalidateDirectoryCache = IMG_TRUE;
1323 sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize;
1326 if(bInvalidateDirectoryCache)
1328 MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo);
1332 MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
1336 MMU_PDumpPageTables(psMMUHeap,
1338 psMMUHeap->ui32DataPageSize * ui32PageCount,
1345 IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
1346 IMG_SIZE_T ui32Start,
1348 IMG_HANDLE hUniqueTag)
1350 MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
1351 IMG_DEV_VIRTADDR Start;
1353 Start.uiAddr = ui32Start;
1355 MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) >> pMMUHeap->ui32PTShift, hUniqueTag);
1359 MMU_Create (MMU_CONTEXT *psMMUContext,
1360 DEV_ARENA_DESCRIPTOR *psDevArena,
1361 RA_ARENA **ppsVMArena)
1364 IMG_UINT32 ui32ScaleSize;
1366 PVR_ASSERT (psDevArena != IMG_NULL);
1368 if (psDevArena == IMG_NULL)
1370 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter"));
1374 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1376 (IMG_VOID **)&pMMUHeap, IMG_NULL,
1378 if (pMMUHeap == IMG_NULL)
1380 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed"));
1384 pMMUHeap->psMMUContext = psMMUContext;
1385 pMMUHeap->psDevArena = psDevArena;
1390 switch(pMMUHeap->psDevArena->ui32DataPageSize)
1394 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K;
1396 #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE)
1399 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K;
1403 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K;
1407 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K;
1411 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M;
1415 pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M;
1419 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size"));
1424 pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize;
1425 pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize;
1426 pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1;
1428 pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth;
1429 pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
1430 pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
1431 pMMUHeap->ui32PTSize = (1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
1433 if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
1435 pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
1437 pMMUHeap->ui32PTECount = pMMUHeap->ui32PTSize >> 2;
1440 pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
1441 pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth;
1442 pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE));
1448 if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask))
1453 PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr
1454 & (pMMUHeap->ui32DataPageMask
1455 | pMMUHeap->ui32PTMask)) == 0);
1459 pMMUHeap->ui32PTETotal = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
1462 pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
1467 pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotal + pMMUHeap->ui32PTECount - 1)
1468 >> pMMUHeap->ui32PTBitWidth;
1471 pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
1472 psDevArena->BaseDevVAddr.uiAddr,
1473 psDevArena->ui32Size,
1475 pMMUHeap->ui32DataPageSize,
1481 if (pMMUHeap->psVMArena == IMG_NULL)
1483 PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed"));
1484 goto ErrorFreePagetables;
1489 if(psDevArena->ui32HeapID == SGX_TILED_HEAP_ID)
1491 IMG_UINT32 ui32RegVal;
1492 IMG_UINT32 ui32XTileStride;
1499 ui32XTileStride = 2;
1501 ui32RegVal = (EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK
1502 & ((psDevArena->BaseDevVAddr.uiAddr>>20)
1503 << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT))
1504 |(EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK
1505 & (((psDevArena->BaseDevVAddr.uiAddr+psDevArena->ui32Size)>>20)
1506 << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT))
1507 |(EUR_CR_BIF_TILE0_CFG_MASK
1508 & (((ui32XTileStride<<1)|8) << EUR_CR_BIF_TILE0_CFG_SHIFT));
1509 PDUMPREG(EUR_CR_BIF_TILE0, ui32RegVal);
1515 *ppsVMArena = pMMUHeap->psVMArena;
1520 ErrorFreePagetables:
1521 _DeferredFreePageTables (pMMUHeap);
1524 OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
1531 MMU_Delete (MMU_HEAP *pMMUHeap)
1533 if (pMMUHeap != IMG_NULL)
1535 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete"));
1537 if(pMMUHeap->psVMArena)
1539 RA_Delete (pMMUHeap->psVMArena);
1542 #ifdef SUPPORT_SGX_MMU_BYPASS
1543 EnableHostAccess(pMMUHeap->psMMUContext);
1545 _DeferredFreePageTables (pMMUHeap);
1546 #ifdef SUPPORT_SGX_MMU_BYPASS
1547 DisableHostAccess(pMMUHeap->psMMUContext);
1550 OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL);
1556 MMU_Alloc (MMU_HEAP *pMMUHeap,
1558 IMG_SIZE_T *pActualSize,
1560 IMG_UINT32 uDevVAddrAlignment,
1561 IMG_DEV_VIRTADDR *psDevVAddr)
1565 PVR_DPF ((PVR_DBG_MESSAGE,
1566 "MMU_Alloc: uSize=0x%x, flags=0x%x, align=0x%x",
1567 uSize, uFlags, uDevVAddrAlignment));
1571 if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
1573 IMG_UINTPTR_T uiAddr;
1575 bStatus = RA_Alloc (pMMUHeap->psVMArena,
1585 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed"));
1589 psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr);
1592 #ifdef SUPPORT_SGX_MMU_BYPASS
1593 EnableHostAccess(pMMUHeap->psMMUContext);
1597 bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize);
1599 #ifdef SUPPORT_SGX_MMU_BYPASS
1600 DisableHostAccess(pMMUHeap->psMMUContext);
1605 PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed"));
1606 if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0)
1609 RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE);
1617 MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size)
1619 PVR_ASSERT (pMMUHeap != IMG_NULL);
1621 if (pMMUHeap == IMG_NULL)
1623 PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter"));
1627 PVR_DPF ((PVR_DBG_MESSAGE,
1628 "MMU_Free: mmu=%08X, dev_vaddr=%08X", pMMUHeap, DevVAddr.uiAddr));
1630 if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) &&
1631 (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size))
1633 RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE);
1637 PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't find DevVAddr %08X in a DevArena",DevVAddr.uiAddr));
1641 MMU_Enable (MMU_HEAP *pMMUHeap)
1643 PVR_UNREFERENCED_PARAMETER(pMMUHeap);
1648 MMU_Disable (MMU_HEAP *pMMUHeap)
1650 PVR_UNREFERENCED_PARAMETER(pMMUHeap);
1656 MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
1657 IMG_DEV_VIRTADDR DevVAddr,
1660 IMG_HANDLE hUniqueTag)
1662 IMG_UINT32 ui32NumPTEntries;
1663 IMG_UINT32 ui32PTIndex;
1664 IMG_UINT32 *pui32PTEntry;
1666 MMU_PT_INFO **ppsPTInfoList;
1667 IMG_UINT32 ui32PDIndex;
1668 IMG_UINT32 ui32PTDumpCount;
1671 ui32NumPTEntries = (uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift;
1674 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
1677 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
1680 ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
1683 PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : "");
1686 while(ui32NumPTEntries > 0)
1688 MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
1690 if(ui32NumPTEntries <= pMMUHeap->ui32PTECount - ui32PTIndex)
1692 ui32PTDumpCount = ui32NumPTEntries;
1696 ui32PTDumpCount = pMMUHeap->ui32PTECount - ui32PTIndex;
1701 pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr;
1702 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag);
1706 ui32NumPTEntries -= ui32PTDumpCount;
1712 PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : "");
1718 MMU_MapPage (MMU_HEAP *pMMUHeap,
1719 IMG_DEV_VIRTADDR DevVAddr,
1720 IMG_DEV_PHYADDR DevPAddr,
1721 IMG_UINT32 ui32MemFlags)
1723 IMG_UINT32 ui32Index;
1724 IMG_UINT32 *pui32Tmp;
1725 IMG_UINT32 ui32MMUFlags = 0;
1726 MMU_PT_INFO **ppsPTInfoList;
1729 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1733 if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE))
1738 else if(PVRSRV_MEM_READ & ui32MemFlags)
1741 ui32MMUFlags |= SGX_MMU_PTE_READONLY;
1743 else if(PVRSRV_MEM_WRITE & ui32MemFlags)
1746 ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY;
1750 if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags)
1752 ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT;
1755 #if !defined(FIX_HW_BRN_25503)
1757 if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags)
1759 ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT;
1767 ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
1770 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
1772 CheckPT(ppsPTInfoList[0]);
1775 ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
1778 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
1780 #if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1782 if (pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID)
1784 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08lX PDIdx:%u PTIdx:%u",
1786 DevVAddr.uiAddr >> pMMUHeap->ui32PDShift,
1788 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08lX", pui32Tmp[ui32Index]));
1789 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08lX", DevPAddr.uiAddr));
1792 PVR_ASSERT((pui32Tmp[ui32Index] & SGX_MMU_PTE_VALID) == 0);
1796 ppsPTInfoList[0]->ui32ValidPTECount++;
1799 pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1800 & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
1804 CheckPT(ppsPTInfoList[0]);
1809 MMU_MapScatter (MMU_HEAP *pMMUHeap,
1810 IMG_DEV_VIRTADDR DevVAddr,
1811 IMG_SYS_PHYADDR *psSysAddr,
1813 IMG_UINT32 ui32MemFlags,
1814 IMG_HANDLE hUniqueTag)
1817 IMG_DEV_VIRTADDR MapBaseDevVAddr;
1819 IMG_UINT32 uCount, i;
1820 IMG_DEV_PHYADDR DevPAddr;
1822 PVR_ASSERT (pMMUHeap != IMG_NULL);
1825 MapBaseDevVAddr = DevVAddr;
1827 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1830 for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize)
1832 IMG_SYS_PHYADDR sSysAddr;
1834 sSysAddr = psSysAddr[i];
1838 PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1840 DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr);
1842 MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
1843 DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize;
1845 PVR_DPF ((PVR_DBG_MESSAGE,
1846 "MMU_MapScatter: devVAddr=%08X, SysAddr=%08X, size=0x%x/0x%x",
1847 DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize));
1851 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
1856 MMU_MapPages (MMU_HEAP *pMMUHeap,
1857 IMG_DEV_VIRTADDR DevVAddr,
1858 IMG_SYS_PHYADDR SysPAddr,
1860 IMG_UINT32 ui32MemFlags,
1861 IMG_HANDLE hUniqueTag)
1863 IMG_DEV_PHYADDR DevPAddr;
1865 IMG_DEV_VIRTADDR MapBaseDevVAddr;
1868 IMG_UINT32 ui32VAdvance;
1869 IMG_UINT32 ui32PAdvance;
1871 PVR_ASSERT (pMMUHeap != IMG_NULL);
1873 PVR_DPF ((PVR_DBG_MESSAGE,
1874 "MMU_MapPages: mmu=%08X, devVAddr=%08X, SysPAddr=%08X, size=0x%x",
1875 pMMUHeap, DevVAddr.uiAddr, SysPAddr.uiAddr, uSize));
1878 ui32VAdvance = pMMUHeap->ui32DataPageSize;
1879 ui32PAdvance = pMMUHeap->ui32DataPageSize;
1882 MapBaseDevVAddr = DevVAddr;
1884 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1887 DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr);
1890 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1892 #if defined(FIX_HW_BRN_23281)
1893 if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
1902 if(ui32MemFlags & PVRSRV_MEM_DUMMY)
1907 for (uCount=0; uCount<uSize; uCount+=ui32VAdvance)
1909 MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags);
1910 DevVAddr.uiAddr += ui32VAdvance;
1911 DevPAddr.uiAddr += ui32PAdvance;
1915 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag);
1920 MMU_MapShadow (MMU_HEAP *pMMUHeap,
1921 IMG_DEV_VIRTADDR MapBaseDevVAddr,
1922 IMG_SIZE_T uByteSize,
1923 IMG_CPU_VIRTADDR CpuVAddr,
1924 IMG_HANDLE hOSMemHandle,
1925 IMG_DEV_VIRTADDR *pDevVAddr,
1926 IMG_UINT32 ui32MemFlags,
1927 IMG_HANDLE hUniqueTag)
1930 IMG_UINT32 uOffset = 0;
1931 IMG_DEV_VIRTADDR MapDevVAddr;
1932 IMG_UINT32 ui32VAdvance;
1933 IMG_UINT32 ui32PAdvance;
1935 #if !defined (PDUMP)
1936 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
1939 PVR_DPF ((PVR_DBG_MESSAGE,
1940 "MMU_MapShadow: %08X, 0x%x, %08X",
1941 MapBaseDevVAddr.uiAddr,
1946 ui32VAdvance = pMMUHeap->ui32DataPageSize;
1947 ui32PAdvance = pMMUHeap->ui32DataPageSize;
1950 PVR_ASSERT(((IMG_UINT32)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
1951 PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0);
1952 pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr;
1954 #if defined(FIX_HW_BRN_23281)
1955 if(ui32MemFlags & PVRSRV_MEM_INTERLEAVED)
1964 if(ui32MemFlags & PVRSRV_MEM_DUMMY)
1970 MapDevVAddr = MapBaseDevVAddr;
1971 for (i=0; i<uByteSize; i+=ui32VAdvance)
1973 IMG_CPU_PHYADDR CpuPAddr;
1974 IMG_DEV_PHYADDR DevPAddr;
1978 CpuPAddr = OSMapLinToCPUPhys ((IMG_VOID *)((IMG_UINT32)CpuVAddr + uOffset));
1982 CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset);
1984 DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr);
1987 PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0);
1989 PVR_DPF ((PVR_DBG_MESSAGE,
1990 "0x%x: CpuVAddr=%08X, CpuPAddr=%08X, DevVAddr=%08X, DevPAddr=%08X",
1992 (IMG_UINTPTR_T)CpuVAddr + uOffset,
1997 MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags);
2000 MapDevVAddr.uiAddr += ui32VAdvance;
2001 uOffset += ui32PAdvance;
2005 MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag);
2011 MMU_UnmapPages (MMU_HEAP *psMMUHeap,
2012 IMG_DEV_VIRTADDR sDevVAddr,
2013 IMG_UINT32 ui32PageCount,
2014 IMG_HANDLE hUniqueTag)
2016 IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize;
2017 IMG_DEV_VIRTADDR sTmpDevVAddr;
2019 IMG_UINT32 ui32PDIndex;
2020 IMG_UINT32 ui32PTIndex;
2021 IMG_UINT32 *pui32Tmp;
2023 #if !defined (PDUMP)
2024 PVR_UNREFERENCED_PARAMETER(hUniqueTag);
2028 sTmpDevVAddr = sDevVAddr;
2030 for(i=0; i<ui32PageCount; i++)
2032 MMU_PT_INFO **ppsPTInfoList;
2035 ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift;
2038 ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
2041 ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift;
2044 if (!ppsPTInfoList[0])
2046 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08lX (VaddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",
2047 sTmpDevVAddr.uiAddr,
2054 sTmpDevVAddr.uiAddr += uPageSize;
2060 CheckPT(ppsPTInfoList[0]);
2063 pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
2066 if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID)
2068 ppsPTInfoList[0]->ui32ValidPTECount--;
2072 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08lX (VAddrIni:0x%08lX AllocPage:%u) PDIdx:%u PTIdx:%u",
2073 sTmpDevVAddr.uiAddr,
2078 PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08lX", pui32Tmp[ui32PTIndex]));
2082 PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
2084 #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
2086 pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2087 | SGX_MMU_PTE_VALID;
2090 pui32Tmp[ui32PTIndex] = 0;
2093 CheckPT(ppsPTInfoList[0]);
2096 sTmpDevVAddr.uiAddr += uPageSize;
2099 MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo);
2102 MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag);
2108 MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr)
2110 IMG_UINT32 *pui32PageTable;
2111 IMG_UINT32 ui32Index;
2112 IMG_DEV_PHYADDR sDevPAddr;
2113 MMU_PT_INFO **ppsPTInfoList;
2116 ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift;
2119 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index];
2120 if (!ppsPTInfoList[0])
2122 PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr));
2123 sDevPAddr.uiAddr = 0;
2128 ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift;
2131 pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr;
2134 sDevPAddr.uiAddr = pui32PageTable[ui32Index];
2137 sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT);
2140 sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT;
2146 IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext)
2148 return (pMMUContext->sPDDevPAddr);
2153 PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap,
2154 IMG_DEV_VIRTADDR sDevVAddr,
2155 IMG_DEV_PHYADDR *pDevPAddr,
2156 IMG_CPU_PHYADDR *pCpuPAddr)
2159 IMG_DEV_PHYADDR DevPAddr;
2163 pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap);
2165 DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr);
2166 pCpuPAddr->uiAddr = DevPAddr.uiAddr;
2167 pDevPAddr->uiAddr = DevPAddr.uiAddr;
2169 return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
2173 PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie,
2174 IMG_HANDLE hDevMemContext,
2175 IMG_DEV_PHYADDR *psPDDevPAddr)
2177 if (!hDevCookie || !hDevMemContext || !psPDDevPAddr)
2179 return PVRSRV_ERROR_INVALID_PARAMS;
2183 *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr;
2188 PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo)
2190 PVRSRV_ERROR eError;
2191 SYS_DATA *psSysData;
2192 RA_ARENA *psLocalDevMemArena;
2193 IMG_HANDLE hOSMemHandle = IMG_NULL;
2194 IMG_BYTE *pui8MemBlock = IMG_NULL;
2195 IMG_SYS_PHYADDR sMemBlockSysPAddr;
2196 IMG_CPU_PHYADDR sMemBlockCpuPAddr;
2198 SysAcquireData(&psSysData);
2200 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2203 if(psLocalDevMemArena == IMG_NULL)
2206 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2207 3 * SGX_MMU_PAGE_SIZE,
2209 (IMG_VOID **)&pui8MemBlock,
2211 if (eError != PVRSRV_OK)
2213 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed"));
2220 sMemBlockCpuPAddr = OSMapLinToCPUPhys(pui8MemBlock);
2225 sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0);
2232 if(RA_Alloc(psLocalDevMemArena,
2233 3 * SGX_MMU_PAGE_SIZE,
2239 &(sMemBlockSysPAddr.uiAddr)) != IMG_TRUE)
2241 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed"));
2242 return PVRSRV_ERROR_OUT_OF_MEMORY;
2246 sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr);
2247 pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr,
2248 SGX_MMU_PAGE_SIZE * 3,
2249 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2253 PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables"));
2254 return PVRSRV_ERROR_BAD_MAPPING;
2258 psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle;
2259 psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr);
2260 psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
2261 psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE;
2264 psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock;
2265 psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE);
2268 OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE);
2269 OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE);
2271 OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE);
2276 IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
2278 SYS_DATA *psSysData;
2279 RA_ARENA *psLocalDevMemArena;
2280 IMG_SYS_PHYADDR sPDSysPAddr;
2282 SysAcquireData(&psSysData);
2284 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2287 if(psLocalDevMemArena == IMG_NULL)
2289 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2290 3 * SGX_MMU_PAGE_SIZE,
2291 psDevInfo->pui32BIFResetPD,
2292 psDevInfo->hBIFResetPDOSMemHandle);
2296 OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD,
2297 3 * SGX_MMU_PAGE_SIZE,
2298 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2299 psDevInfo->hBIFResetPDOSMemHandle);
2301 sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr);
2302 RA_Free(psLocalDevMemArena, sPDSysPAddr.uiAddr, IMG_FALSE);
2307 #if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
2308 PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_SGXDEV_INFO *psDevInfo)
2310 PVRSRV_ERROR eError;
2311 SYS_DATA *psSysData;
2312 RA_ARENA *psLocalDevMemArena;
2313 IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
2314 IMG_HANDLE hPDPageOSMemHandle = IMG_NULL;
2315 IMG_UINT32 *pui32PD = IMG_NULL;
2316 IMG_UINT32 *pui32PT = IMG_NULL;
2317 IMG_CPU_PHYADDR sCpuPAddr;
2318 IMG_DEV_PHYADDR sPTDevPAddr;
2319 IMG_DEV_PHYADDR sPDDevPAddr;
2321 SysAcquireData(&psSysData);
2323 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2326 if(psLocalDevMemArena == IMG_NULL)
2329 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2332 (IMG_VOID **)&pui32PT,
2333 &hPTPageOSMemHandle);
2334 if (eError != PVRSRV_OK)
2336 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
2340 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2343 (IMG_VOID **)&pui32PD,
2344 &hPDPageOSMemHandle);
2345 if (eError != PVRSRV_OK)
2347 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to OSAllocPages failed"));
2354 sCpuPAddr = OSMapLinToCPUPhys(pui32PT);
2359 sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
2361 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2365 sCpuPAddr = OSMapLinToCPUPhys(pui32PD);
2370 sCpuPAddr = OSMemHandleToCpuPAddr(hPDPageOSMemHandle, 0);
2372 sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2379 if(RA_Alloc(psLocalDevMemArena,
2380 SGX_MMU_PAGE_SIZE * 2,
2386 &(psDevInfo->sBRN22997SysPAddr.uiAddr))!= IMG_TRUE)
2388 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR call to RA_Alloc failed"));
2389 return PVRSRV_ERROR_OUT_OF_MEMORY;
2393 sCpuPAddr = SysSysPAddrToCpuPAddr(psDevInfo->sBRN22997SysPAddr);
2394 pui32PT = OSMapPhysToLin(sCpuPAddr,
2395 SGX_MMU_PAGE_SIZE * 2,
2396 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2397 &hPTPageOSMemHandle);
2400 PVR_DPF((PVR_DBG_ERROR, "WorkaroundBRN22997: ERROR failed to map page tables"));
2401 return PVRSRV_ERROR_BAD_MAPPING;
2405 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2407 pui32PD = pui32PT + 1024;
2408 sPDDevPAddr.uiAddr = sPTDevPAddr.uiAddr + 4096;
2411 OSMemSet(pui32PD, 0, SGX_MMU_PAGE_SIZE);
2412 OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
2415 PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
2416 PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2417 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2418 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2420 psDevInfo->hBRN22997PTPageOSMemHandle = hPTPageOSMemHandle;
2421 psDevInfo->hBRN22997PDPageOSMemHandle = hPDPageOSMemHandle;
2422 psDevInfo->sBRN22997PTDevPAddr = sPTDevPAddr;
2423 psDevInfo->sBRN22997PDDevPAddr = sPDDevPAddr;
2424 psDevInfo->pui32BRN22997PD = pui32PD;
2425 psDevInfo->pui32BRN22997PT = pui32PT;
2431 IMG_VOID WorkaroundBRN22997ReadHostPort(PVRSRV_SGXDEV_INFO *psDevInfo)
2433 IMG_UINT32 *pui32PD = psDevInfo->pui32BRN22997PD;
2434 IMG_UINT32 *pui32PT = psDevInfo->pui32BRN22997PT;
2435 IMG_UINT32 ui32PDIndex;
2436 IMG_UINT32 ui32PTIndex;
2437 IMG_DEV_VIRTADDR sDevVAddr;
2438 volatile IMG_UINT32 *pui32HostPort;
2439 IMG_UINT32 ui32BIFCtrl;
2444 pui32HostPort = (volatile IMG_UINT32*)(((IMG_UINT8*)psDevInfo->pvHostPortBaseKM) + SYS_SGX_HOSTPORT_BRN23030_OFFSET);
2447 sDevVAddr.uiAddr = SYS_SGX_HOSTPORT_BASE_DEVVADDR + SYS_SGX_HOSTPORT_BRN23030_OFFSET;
2449 ui32PDIndex = (sDevVAddr.uiAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2450 ui32PTIndex = (sDevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
2453 pui32PD[ui32PDIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
2454 | SGX_MMU_PDE_VALID;
2456 pui32PT[ui32PTIndex] = (psDevInfo->sBRN22997PTDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2457 | SGX_MMU_PTE_VALID;
2459 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2460 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2463 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0,
2464 psDevInfo->sBRN22997PDDevPAddr.uiAddr);
2465 PDUMPPDREG(EUR_CR_BIF_DIR_LIST_BASE0, psDevInfo->sBRN22997PDDevPAddr.uiAddr, PDUMP_PD_UNIQUETAG);
2468 ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL);
2469 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2470 PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2471 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2472 PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl);
2479 ui32Tmp = *pui32HostPort;
2483 PVR_DPF((PVR_DBG_ERROR,"Host Port not present for BRN22997 workaround"));
2492 PDUMPCOMMENT("RDW :SGXMEM:v4:%08lX\r\n", sDevVAddr.uiAddr);
2494 PDUMPCOMMENT("SAB :SGXMEM:v4:%08lX 4 0 hostport.bin", sDevVAddr.uiAddr);
2497 pui32PD[ui32PDIndex] = 0;
2498 pui32PT[ui32PTIndex] = 0;
2501 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2502 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2504 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2505 PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_INVALDC_MASK);
2506 OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl);
2507 PDUMPREG(EUR_CR_BIF_CTRL, ui32BIFCtrl);
2511 IMG_VOID WorkaroundBRN22997Free(PVRSRV_SGXDEV_INFO *psDevInfo)
2513 SYS_DATA *psSysData;
2514 RA_ARENA *psLocalDevMemArena;
2516 SysAcquireData(&psSysData);
2518 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2520 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PD, SGX_MMU_PAGE_SIZE, PDUMP_PD_UNIQUETAG);
2521 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32BRN22997PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2524 if(psLocalDevMemArena == IMG_NULL)
2526 if (psDevInfo->pui32BRN22997PD != IMG_NULL)
2528 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2530 psDevInfo->pui32BRN22997PD,
2531 psDevInfo->hBRN22997PDPageOSMemHandle);
2534 if (psDevInfo->pui32BRN22997PT != IMG_NULL)
2536 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2538 psDevInfo->pui32BRN22997PT,
2539 psDevInfo->hBRN22997PTPageOSMemHandle);
2544 if (psDevInfo->pui32BRN22997PT != IMG_NULL)
2546 OSUnMapPhysToLin(psDevInfo->pui32BRN22997PT,
2547 SGX_MMU_PAGE_SIZE * 2,
2548 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2549 psDevInfo->hBRN22997PTPageOSMemHandle);
2552 RA_Free(psLocalDevMemArena, psDevInfo->sBRN22997SysPAddr.uiAddr, IMG_FALSE);
2559 #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE)
2560 PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
2562 PVRSRV_ERROR eError;
2563 SYS_DATA *psSysData;
2564 RA_ARENA *psLocalDevMemArena;
2565 IMG_HANDLE hPTPageOSMemHandle = IMG_NULL;
2566 IMG_UINT32 *pui32PD;
2567 IMG_UINT32 *pui32PT = IMG_NULL;
2568 IMG_CPU_PHYADDR sCpuPAddr;
2569 IMG_DEV_PHYADDR sPTDevPAddr;
2570 PVRSRV_SGXDEV_INFO *psDevInfo;
2571 IMG_UINT32 ui32PDIndex;
2572 IMG_UINT32 ui32PTIndex;
2574 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2575 pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
2577 SysAcquireData(&psSysData);
2579 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2582 if(psLocalDevMemArena == IMG_NULL)
2585 eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2588 (IMG_VOID **)&pui32PT,
2589 &hPTPageOSMemHandle);
2590 if (eError != PVRSRV_OK)
2592 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to OSAllocPages failed"));
2599 sCpuPAddr = OSMapLinToCPUPhys(pui32PT);
2604 sCpuPAddr = OSMemHandleToCpuPAddr(hPTPageOSMemHandle, 0);
2606 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2610 IMG_SYS_PHYADDR sSysPAddr;
2613 if(RA_Alloc(psLocalDevMemArena,
2620 &(sSysPAddr.uiAddr))!= IMG_TRUE)
2622 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR call to RA_Alloc failed"));
2623 return PVRSRV_ERROR_OUT_OF_MEMORY;
2627 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
2628 pui32PT = OSMapPhysToLin(sCpuPAddr,
2630 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2631 &hPTPageOSMemHandle);
2634 PVR_DPF((PVR_DBG_ERROR, "MMU_MapExtSystemCacheRegs: ERROR failed to map page tables"));
2635 return PVRSRV_ERROR_BAD_MAPPING;
2639 sPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
2642 psDevInfo->sExtSystemCacheRegsPTSysPAddr = sSysPAddr;
2645 OSMemSet(pui32PT, 0, SGX_MMU_PAGE_SIZE);
2647 ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2648 ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
2651 pui32PD[ui32PDIndex] = (sPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
2652 | SGX_MMU_PDE_VALID;
2654 pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
2655 | SGX_MMU_PTE_VALID;
2658 PDUMPMALLOCPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2659 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2660 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2663 psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT;
2664 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle = hPTPageOSMemHandle;
2670 PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
2672 SYS_DATA *psSysData;
2673 RA_ARENA *psLocalDevMemArena;
2674 PVRSRV_SGXDEV_INFO *psDevInfo;
2675 IMG_UINT32 ui32PDIndex;
2676 IMG_UINT32 *pui32PD;
2678 psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice;
2679 pui32PD = (IMG_UINT32*)psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->pvPDCpuVAddr;
2681 SysAcquireData(&psSysData);
2683 psLocalDevMemArena = psSysData->apsLocalDevMemArena[0];
2686 ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);
2687 pui32PD[ui32PDIndex] = 0;
2689 PDUMPMEM2(PVRSRV_DEVICE_TYPE_SGX, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2690 PDUMPFREEPAGETABLE(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->pui32ExtSystemCacheRegsPT, SGX_MMU_PAGE_SIZE, PDUMP_PT_UNIQUETAG);
2693 if(psLocalDevMemArena == IMG_NULL)
2695 if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
2697 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
2699 psDevInfo->pui32ExtSystemCacheRegsPT,
2700 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
2705 if (psDevInfo->pui32ExtSystemCacheRegsPT != IMG_NULL)
2707 OSUnMapPhysToLin(psDevInfo->pui32ExtSystemCacheRegsPT,
2709 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
2710 psDevInfo->hExtSystemCacheRegsPTPageOSMemHandle);
2712 RA_Free(psLocalDevMemArena, psDevInfo->sExtSystemCacheRegsPTSysPAddr.uiAddr, IMG_FALSE);
2722 static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr)
2724 volatile IMG_UINT32 ui32WriteData;
2725 volatile IMG_UINT32 ui32ReadData;
2726 volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem;
2728 IMG_BOOL bOK=IMG_TRUE;
2730 ui32WriteData = 0xffffffff;
2732 for (n=0; n<1024; n++)
2734 pMem32[n] = ui32WriteData;
2735 ui32ReadData = pMem32[n];
2737 if (ui32WriteData != ui32ReadData)
2740 PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
2748 for (n=0; n<1024; n++)
2750 pMem32[n] = ui32WriteData;
2751 ui32ReadData = pMem32[n];
2753 if (ui32WriteData != ui32ReadData)
2756 PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x%08X", sDevPAddr.uiAddr + (n<<2) ));
2764 PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X is OK", sDevPAddr.uiAddr));
2768 PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x%08X *** FAILED ***", sDevPAddr.uiAddr));