aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/sgx/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/sgx/mmu.c')
-rw-r--r--drivers/gpu/pvr/sgx/mmu.c210
1 files changed, 202 insertions, 8 deletions
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
index 774026d..9d124f5 100644
--- a/drivers/gpu/pvr/sgx/mmu.c
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -248,6 +248,111 @@ static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList)
}
#endif
+#if defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND)
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#else
+#include <generated/autoconf.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_mkwrite(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+}
+
+static IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ pgd_t *psPGD;
+ pud_t *psPUD;
+ pmd_t *psPMD;
+ pte_t *psPTE;
+ pte_t ptent;
+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr;
+
+ OSWriteMemoryBarrier();
+
+ psPGD = pgd_offset_k(ui32CPUVAddr);
+ if (pgd_none(*psPGD) || pgd_bad(*psPGD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPUD = pud_offset(psPGD, ui32CPUVAddr);
+ if (pud_none(*psPUD) || pud_bad(*psPUD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPMD = pmd_offset(psPUD, ui32CPUVAddr);
+ if (pmd_none(*psPMD) || pmd_bad(*psPMD))
+ {
+ PVR_ASSERT(0);
+ }
+
+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr);
+
+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE);
+ ptent = pte_wrprotect(ptent);
+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent);
+
+ flush_tlb_all();
+
+}
+
+#else
+
+static INLINE IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+static INLINE IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr)
+{
+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr);
+}
+
+#endif
IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap)
{
@@ -401,11 +506,13 @@ static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDInde
psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+ MakeKernelPageReadWrite(psMMUContextWalker->pvPDCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContextWalker->pvPDCpuVAddr);
PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -417,11 +524,13 @@ static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDInde
psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -461,6 +570,11 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
}
+
+
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
+
+
if(psPTInfoList->PTPageCpuVAddr)
{
sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle,
@@ -518,6 +632,7 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
#endif
}
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
{
IMG_UINT32 *pui32Tmp;
@@ -540,6 +655,7 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize);
#endif
+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr);
#if defined(PDUMP)
{
@@ -572,6 +688,9 @@ _FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList)
if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL)
{
+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr);
+
+
OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
pMMUHeap->ui32PTSize,
psPTInfoList->PTPageCpuVAddr,
@@ -659,6 +778,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
while(psMMUContext)
{
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -675,6 +795,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32PDEntry[ui32PTIndex] = 0;
}
#endif
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
#if defined(PDUMP)
#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
@@ -692,6 +813,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
case DEVICE_MEMORY_HEAP_PERCONTEXT :
case DEVICE_MEMORY_HEAP_KERNEL :
{
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -709,6 +831,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32PDEntry[ui32PTIndex] = 0;
}
#endif
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -728,6 +851,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
{
IMG_PUINT32 pui32Tmp;
+ MakeKernelPageReadWrite(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr;
@@ -738,6 +862,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr);
@@ -1040,6 +1165,7 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
while(psMMUContext)
{
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr;
pui32PDEntry += ui32PDIndex;
@@ -1048,6 +1174,7 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| pMMUHeap->ui32PDEPageSizeCtrl
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
#if defined(PDUMP)
#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
@@ -1069,11 +1196,12 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
case DEVICE_MEMORY_HEAP_PERCONTEXT :
case DEVICE_MEMORY_HEAP_KERNEL :
{
+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr);
pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| pMMUHeap->ui32PDEPageSizeCtrl
| SGX_MMU_PDE_VALID;
-
+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr);
PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
@@ -1185,13 +1313,14 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
PVR_ASSERT(psTempPTInfo != IMG_NULL);
+ MakeKernelPageReadWrite(psTempPTInfo->PTPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
PVR_ASSERT(pui32Tmp != IMG_NULL);
pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_DUMMY_PAGE
| SGX_MMU_PTE_READONLY
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(psTempPTInfo->PTPageCpuVAddr);
PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
}
@@ -1564,11 +1693,13 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
}
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
{
pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
}
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPageCpuVAddr);
PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
@@ -1659,6 +1790,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
@@ -1666,40 +1798,47 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_VALID;
}
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
if(!psDevInfo->pvMMUContextList)
{
+ MakeKernelPageReadWrite(psDevInfo->pvDummyPTPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr;
for(i=0; i<SGX_MMU_PT_SIZE; i++)
{
pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_VALID;
}
+ MakeKernelPageReadOnly(psDevInfo->pvDummyPTPageCpuVAddr);
PDUMPCOMMENT("Dummy Page table contents");
PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
+ MakeKernelPageReadWrite(psDevInfo->pvDummyDataPageCpuVAddr);
pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr;
for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++)
{
pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE;
}
+ MakeKernelPageReadOnly(psDevInfo->pvDummyDataPageCpuVAddr);
PDUMPCOMMENT("Dummy Data Page contents");
PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
}
#else
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
#endif
#if defined(PDUMP)
@@ -1721,12 +1860,13 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
PDUMPCOMMENT("BRN31620 Set up dummy PT");
+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPTCpuVAddr);
pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_DUMMY_PAGE
| SGX_MMU_PTE_READONLY
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPTCpuVAddr);
#if defined(PDUMP)
@@ -1749,10 +1889,12 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
{
+ MakeKernelPageReadWrite(pvPDCpuVAddr);
pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
| SGX_MMU_PDE_PAGE_SIZE_4K
| SGX_MMU_PDE_DUMMY_PAGE
| SGX_MMU_PDE_VALID;
+ MakeKernelPageReadOnly(pvPDCpuVAddr);
}
PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
ui32PDCount++;
@@ -1876,12 +2018,14 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr;
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
for(i=0; i<SGX_MMU_PD_SIZE; i++)
{
pui32Tmp[i] = 0;
}
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
@@ -1892,6 +2036,7 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
#if defined(FIX_HW_BRN_31620)
PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
#endif
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
SGX_MMU_PAGE_SIZE,
psMMUContext->pvPDCpuVAddr,
@@ -2073,9 +2218,10 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
#endif
-
+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr);
pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr);
if (pui32PDCpuVAddr[ui32PDEntry])
{
@@ -2179,7 +2325,7 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
-
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
@@ -2192,7 +2338,7 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
pui32Tmp[ui32PTIndex] = 0;
#endif
#endif
-
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
}
@@ -2771,12 +2917,13 @@ MMU_MapPage (MMU_HEAP *pMMUHeap,
ppsPTInfoList[0]->ui32ValidPTECount++;
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
pui32Tmp[ui32Index] = ((DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
& ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT))
| SGX_MMU_PTE_VALID
| ui32MMUFlags;
-
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
}
@@ -3061,6 +3208,7 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap,
PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0);
+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr);
#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
@@ -3073,6 +3221,7 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap,
pui32Tmp[ui32PTIndex] = 0;
#endif
#endif
+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr);
CheckPT(ppsPTInfoList[0]);
@@ -3292,6 +3441,48 @@ IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo)
}
}
+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32FaultAddr)
+{
+ MMU_CONTEXT *psMMUContext = psDevInfo->pvMMUContextList;
+
+ while (psMMUContext && (psMMUContext->sPDDevPAddr.uiAddr != ui32PDDevPAddr))
+ {
+ psMMUContext = psMMUContext->psNext;
+ }
+
+ if (psMMUContext)
+ {
+ IMG_UINT32 ui32PTIndex;
+ IMG_UINT32 ui32PDIndex;
+
+ PVR_LOG(("Found MMU context for page fault 0x%08x", ui32FaultAddr));
+
+ ui32PTIndex = (ui32FaultAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT;
+ ui32PDIndex = (ui32FaultAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PT_SHIFT + SGX_MMU_PAGE_SHIFT);
+
+ if (psMMUContext->apsPTInfoList[ui32PDIndex])
+ {
+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
+ {
+ IMG_UINT32 *pui32Ptr = psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ IMG_UINT32 ui32PTE = pui32Ptr[ui32PTIndex];
+
+ PVR_LOG(("PDE valid: PTE = 0x%08x (PhysAddr = 0x%08x, %s)",
+ ui32PTE,
+ ui32PTE & SGX_MMU_PTE_ADDR_MASK,
+ ui32PTE & SGX_MMU_PTE_VALID?"valid":"Invalid"));
+ }
+ else
+ {
+ PVR_LOG(("Found PT info but no CPU address"));
+ }
+ }
+ else
+ {
+ PVR_LOG(("No PDE found"));
+ }
+ }
+}
#if defined(FIX_HW_BRN_22997) && defined(FIX_HW_BRN_23030) && defined(SGX_FEATURE_HOST_PORT)
PVRSRV_ERROR WorkaroundBRN22997Alloc(PVRSRV_DEVICE_NODE *psDeviceNode)
@@ -3597,10 +3788,11 @@ PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
+ MakeKernelPageReadWrite(pui32PT);
pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
| SGX_MMU_PTE_VALID;
-
+ MakeKernelPageReadOnly(pui32PT);
#if defined(PDUMP)
{
@@ -3676,7 +3868,9 @@ PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
}
}
+ MakeKernelPageReadWrite(pui32PT);
pui32PT[ui32PTIndex] = 0;
+ MakeKernelPageReadOnly(pui32PT);
PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);