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.c806
1 files changed, 758 insertions, 48 deletions
diff --git a/drivers/gpu/pvr/sgx/mmu.c b/drivers/gpu/pvr/sgx/mmu.c
index 2685fbf169f..67e86d92025 100644
--- a/drivers/gpu/pvr/sgx/mmu.c
+++ b/drivers/gpu/pvr/sgx/mmu.c
@@ -42,6 +42,38 @@
42 42
43#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT)) 43#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT))
44 44
45#if defined(FIX_HW_BRN_31620)
46#define SGX_MMU_PDE_DUMMY_PAGE (0)
47#define SGX_MMU_PTE_DUMMY_PAGE (0)
48
49#define BRN31620_PT_ADDRESS_RANGE_SHIFT 22
50#define BRN31620_PT_ADDRESS_RANGE_SIZE (1 << BRN31620_PT_ADDRESS_RANGE_SHIFT)
51
52#define BRN31620_PDE_CACHE_FILL_SHIFT 26
53#define BRN31620_PDE_CACHE_FILL_SIZE (1 << BRN31620_PDE_CACHE_FILL_SHIFT)
54#define BRN31620_PDE_CACHE_FILL_MASK (BRN31620_PDE_CACHE_FILL_SIZE - 1)
55
56#define BRN31620_PDES_PER_CACHE_LINE_SHIFT (BRN31620_PDE_CACHE_FILL_SHIFT - BRN31620_PT_ADDRESS_RANGE_SHIFT)
57#define BRN31620_PDES_PER_CACHE_LINE_SIZE (1 << BRN31620_PDES_PER_CACHE_LINE_SHIFT)
58#define BRN31620_PDES_PER_CACHE_LINE_MASK (BRN31620_PDES_PER_CACHE_LINE_SIZE - 1)
59
60#define BRN31620_DUMMY_PAGE_OFFSET (1 * SGX_MMU_PAGE_SIZE)
61#define BRN31620_DUMMY_PDE_INDEX (BRN31620_DUMMY_PAGE_OFFSET / BRN31620_PT_ADDRESS_RANGE_SIZE)
62#define BRN31620_DUMMY_PTE_INDEX ((BRN31620_DUMMY_PAGE_OFFSET - (BRN31620_DUMMY_PDE_INDEX * BRN31620_PT_ADDRESS_RANGE_SIZE))/SGX_MMU_PAGE_SIZE)
63
64#define BRN31620_CACHE_FLUSH_SHIFT (32 - BRN31620_PDE_CACHE_FILL_SHIFT)
65#define BRN31620_CACHE_FLUSH_SIZE (1 << BRN31620_CACHE_FLUSH_SHIFT)
66
67#define BRN31620_CACHE_FLUSH_BITS_SHIFT 5
68#define BRN31620_CACHE_FLUSH_BITS_SIZE (1 << BRN31620_CACHE_FLUSH_BITS_SHIFT)
69#define BRN31620_CACHE_FLUSH_BITS_MASK (BRN31620_CACHE_FLUSH_BITS_SIZE - 1)
70
71#define BRN31620_CACHE_FLUSH_INDEX_BITS (BRN31620_CACHE_FLUSH_SHIFT - BRN31620_CACHE_FLUSH_BITS_SHIFT)
72#define BRN31620_CACHE_FLUSH_INDEX_SIZE (1 << BRN31620_CACHE_FLUSH_INDEX_BITS)
73
74#define BRN31620_DUMMY_PAGE_SIGNATURE 0xFEEBEE01
75#endif
76
45typedef struct _MMU_PT_INFO_ 77typedef struct _MMU_PT_INFO_
46{ 78{
47 79
@@ -73,6 +105,11 @@ struct _MMU_CONTEXT_
73#endif 105#endif
74#endif 106#endif
75 107
108#if defined (FIX_HW_BRN_31620)
109 IMG_UINT32 ui32PDChangeMask[BRN31620_CACHE_FLUSH_INDEX_SIZE];
110 IMG_UINT32 ui32PDCacheRangeRefCount[BRN31620_CACHE_FLUSH_SIZE];
111 MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES];
112#endif
76 struct _MMU_CONTEXT_ *psNext; 113 struct _MMU_CONTEXT_ *psNext;
77}; 114};
78 115
@@ -88,7 +125,7 @@ struct _MMU_HEAP_
88 125
89 IMG_UINT32 ui32PageTableCount; 126 IMG_UINT32 ui32PageTableCount;
90 127
91 IMG_UINT32 ui32PTETotal; 128 IMG_UINT32 ui32PTETotalUsable;
92 129
93 IMG_UINT32 ui32PDEPageSizeCtrl; 130 IMG_UINT32 ui32PDEPageSizeCtrl;
94 131
@@ -112,7 +149,9 @@ struct _MMU_HEAP_
112 149
113 IMG_UINT32 ui32PTSize; 150 IMG_UINT32 ui32PTSize;
114 151
115 IMG_UINT32 ui32PTECount; 152 IMG_UINT32 ui32PTNumEntriesAllocated;
153
154 IMG_UINT32 ui32PTNumEntriesUsable;
116 155
117 156
118 157
@@ -138,6 +177,9 @@ struct _MMU_HEAP_
138#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF 177#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF
139#endif 178#endif
140 179
180static IMG_VOID
181_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT);
182
141#if defined(PDUMP) 183#if defined(PDUMP)
142static IMG_VOID 184static IMG_VOID
143MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, 185MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
@@ -285,6 +327,105 @@ static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo)
285 #endif 327 #endif
286} 328}
287 329
330#if defined(FIX_HW_BRN_31620)
331static IMG_VOID BRN31620InvalidatePageTableEntry(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32PDIndex, IMG_UINT32 ui32PTIndex, IMG_UINT32 *pui32PTE)
332{
333 PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
334
335
336 if (((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX)
337 && (ui32PTIndex == BRN31620_DUMMY_PTE_INDEX))
338 {
339 *pui32PTE = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
340 | SGX_MMU_PTE_DUMMY_PAGE
341 | SGX_MMU_PTE_READONLY
342 | SGX_MMU_PTE_VALID;
343 }
344 else
345 {
346 *pui32PTE = 0;
347 }
348}
349
350static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDIndex)
351{
352 MMU_CONTEXT *psMMUContext = psMMUHeap->psMMUContext;
353 PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
354 IMG_UINT32 ui32PDCacheLine = ui32PDIndex >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
355 IMG_UINT32 bFreePTs = IMG_FALSE;
356 IMG_UINT32 *pui32Tmp;
357
358 PVR_ASSERT(psMMUHeap != IMG_NULL);
359
360
361 PVR_ASSERT(psMMUContext->apsPTInfoListSave[ui32PDIndex] == IMG_NULL);
362
363 psMMUContext->apsPTInfoListSave[ui32PDIndex] = psMMUContext->apsPTInfoList[ui32PDIndex];
364 psMMUContext->apsPTInfoList[ui32PDIndex] = IMG_NULL;
365
366
367 if (--psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine] == 0)
368 {
369 IMG_UINT32 i;
370 IMG_UINT32 ui32PDIndexStart = ui32PDCacheLine * BRN31620_PDES_PER_CACHE_LINE_SIZE;
371 IMG_UINT32 ui32PDIndexEnd = ui32PDIndexStart + BRN31620_PDES_PER_CACHE_LINE_SIZE;
372 IMG_UINT32 ui32PDBitMaskIndex, ui32PDBitMaskShift;
373
374
375 for (i=ui32PDIndexStart;i<ui32PDIndexEnd;i++)
376 {
377
378 psMMUContext->apsPTInfoList[i] = psMMUContext->apsPTInfoListSave[i];
379 psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
380 _DeferredFreePageTable(psMMUHeap, i - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
381 }
382
383 ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
384 ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
385
386
387 if (MMU_IsHeapShared(psMMUHeap))
388 {
389
390 MMU_CONTEXT *psMMUContextWalker = (MMU_CONTEXT*) psMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
391
392 while(psMMUContextWalker)
393 {
394 psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
395
396
397 pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr;
398 pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
399 | SGX_MMU_PDE_PAGE_SIZE_4K
400 | SGX_MMU_PDE_DUMMY_PAGE
401 | SGX_MMU_PDE_VALID;
402
403 PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
404 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);
405 psMMUContextWalker = psMMUContextWalker->psNext;
406 }
407 }
408 else
409 {
410 psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
411
412
413 pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr;
414 pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
415 | SGX_MMU_PDE_PAGE_SIZE_4K
416 | SGX_MMU_PDE_DUMMY_PAGE
417 | SGX_MMU_PDE_VALID;
418
419 PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block");
420 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);
421 }
422
423 bFreePTs = IMG_TRUE;
424 }
425
426 return bFreePTs;
427}
428#endif
288 429
289static IMG_BOOL 430static IMG_BOOL
290_AllocPageTableMemory (MMU_HEAP *pMMUHeap, 431_AllocPageTableMemory (MMU_HEAP *pMMUHeap,
@@ -373,11 +514,16 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
373 514
374 pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr; 515 pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr;
375 516
376 for(i=0; i<pMMUHeap->ui32PTECount; i++) 517 for(i=0; i<pMMUHeap->ui32PTNumEntriesUsable; i++)
377 { 518 {
378 pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) 519 pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
379 | SGX_MMU_PTE_VALID; 520 | SGX_MMU_PTE_VALID;
380 } 521 }
522
523 for(; i<pMMUHeap->ui32PTNumEntriesAllocated; i++)
524 {
525 pui32Tmp[i] = 0;
526 }
381 } 527 }
382#else 528#else
383 529
@@ -388,12 +534,12 @@ _AllocPageTableMemory (MMU_HEAP *pMMUHeap,
388 { 534 {
389 IMG_UINT32 ui32Flags = 0; 535 IMG_UINT32 ui32Flags = 0;
390#if defined(SUPPORT_PDUMP_MULTI_PROCESS) 536#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
391 537
392 ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0; 538 ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
393#endif 539#endif
394 540
395 PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG); 541 PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG);
396 542
397 PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); 543 PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
398 } 544 }
399#endif 545#endif
@@ -482,7 +628,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
482#if defined(SUPPORT_PDUMP_MULTI_PROCESS) 628#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
483 ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0; 629 ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0;
484#endif 630#endif
485 631
486 PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); 632 PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
487 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr) 633 if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr)
488 { 634 {
@@ -575,9 +721,10 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
575 721
576 722
577 for(i=0; 723 for(i=0;
578 (i<pMMUHeap->ui32PTETotal) && (i<pMMUHeap->ui32PTECount); 724 (i<pMMUHeap->ui32PTETotalUsable) && (i<pMMUHeap->ui32PTNumEntriesUsable);
579 i++) 725 i++)
580 { 726 {
727
581 pui32Tmp[i] = 0; 728 pui32Tmp[i] = 0;
582 } 729 }
583 730
@@ -591,12 +738,12 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
591 738
592 739
593 740
594 pMMUHeap->ui32PTETotal -= i; 741 pMMUHeap->ui32PTETotalUsable -= i;
595 } 742 }
596 else 743 else
597 { 744 {
598 745
599 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount; 746 pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
600 } 747 }
601 748
602 if(bOSFreePT) 749 if(bOSFreePT)
@@ -612,7 +759,7 @@ _DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOS
612 else 759 else
613 { 760 {
614 761
615 pMMUHeap->ui32PTETotal -= pMMUHeap->ui32PTECount; 762 pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable;
616 } 763 }
617 764
618 PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); 765 PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount);
@@ -622,17 +769,59 @@ static IMG_VOID
622_DeferredFreePageTables (MMU_HEAP *pMMUHeap) 769_DeferredFreePageTables (MMU_HEAP *pMMUHeap)
623{ 770{
624 IMG_UINT32 i; 771 IMG_UINT32 i;
772#if defined(FIX_HW_BRN_31620)
773 MMU_CONTEXT *psMMUContext = pMMUHeap->psMMUContext;
774 IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE;
775 IMG_UINT32 ui32PDIndex;
776 IMG_UINT32 *pui32Tmp;
777 IMG_UINT32 j;
778#endif
625#if defined(PDUMP) 779#if defined(PDUMP)
626 PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)", 780 PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)",
627 pMMUHeap->psMMUContext->ui32PDumpMMUContextID, 781 pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
628 pMMUHeap->ui32PDBaseIndex, 782 pMMUHeap->ui32PDBaseIndex,
629 pMMUHeap->ui32PageTableCount); 783 pMMUHeap->ui32PageTableCount);
630#endif 784#endif
785#if defined(FIX_HW_BRN_31620)
786 for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
787 {
788 ui32PDIndex = (pMMUHeap->ui32PDBaseIndex + i);
789
790 if (psMMUContext->apsPTInfoList[ui32PDIndex])
791 {
792 if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr)
793 {
794
795 for (j=0;j<SGX_MMU_PT_SIZE;j++)
796 {
797 pui32Tmp = (IMG_UINT32 *) psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr;
798 BRN31620InvalidatePageTableEntry(psMMUContext, ui32PDIndex, j, &pui32Tmp[j]);
799 }
800 }
801
802 if (BRN31620FreePageTable(pMMUHeap, ui32PDIndex) == IMG_TRUE)
803 {
804 bInvalidateDirectoryCache = IMG_TRUE;
805 }
806 }
807 }
808
809
810 if (bInvalidateDirectoryCache)
811 {
812 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
813 }
814 else
815 {
816 MMU_InvalidatePageTableCache(pMMUHeap->psMMUContext->psDevInfo);
817 }
818#else
631 for(i=0; i<pMMUHeap->ui32PageTableCount; i++) 819 for(i=0; i<pMMUHeap->ui32PageTableCount; i++)
632 { 820 {
633 _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE); 821 _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE);
634 } 822 }
635 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); 823 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
824#endif
636} 825}
637 826
638 827
@@ -646,6 +835,15 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
646 MMU_PT_INFO **ppsPTInfoList; 835 MMU_PT_INFO **ppsPTInfoList;
647 SYS_DATA *psSysData; 836 SYS_DATA *psSysData;
648 IMG_DEV_VIRTADDR sHighDevVAddr; 837 IMG_DEV_VIRTADDR sHighDevVAddr;
838#if defined(FIX_HW_BRN_31620)
839 IMG_BOOL bFlushSystemCache = IMG_FALSE;
840 IMG_BOOL bSharedPT = IMG_FALSE;
841 IMG_DEV_VIRTADDR sDevVAddrRequestStart;
842 IMG_DEV_VIRTADDR sDevVAddrRequestEnd;
843 IMG_UINT32 ui32PDRequestStart;
844 IMG_UINT32 ui32PDRequestEnd;
845 IMG_UINT32 ui32ModifiedCachelines[BRN31620_CACHE_FLUSH_INDEX_SIZE];
846#endif
649 847
650 848
651#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32 849#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32
@@ -676,6 +874,38 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
676 874
677 ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; 875 ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
678 876
877
878 if (ui32PageTableCount == 0)
879 ui32PageTableCount = 1024;
880
881#if defined(FIX_HW_BRN_31620)
882 for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
883 {
884 ui32ModifiedCachelines[i] = 0;
885 }
886
887
888
889
890 sDevVAddrRequestStart = DevVAddr;
891 ui32PDRequestStart = ui32PDIndex;
892 sDevVAddrRequestEnd = sHighDevVAddr;
893 ui32PDRequestEnd = ui32PageTableCount - 1;
894
895
896 DevVAddr.uiAddr = DevVAddr.uiAddr & (~BRN31620_PDE_CACHE_FILL_MASK);
897
898
899 sHighDevVAddr.uiAddr = ((sHighDevVAddr.uiAddr + (BRN31620_PDE_CACHE_FILL_SIZE - 1)) & (~BRN31620_PDE_CACHE_FILL_MASK));
900
901 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
902 ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
903
904
905 if (ui32PageTableCount == 0)
906 ui32PageTableCount = 1024;
907#endif
908
679 ui32PageTableCount -= ui32PDIndex; 909 ui32PageTableCount -= ui32PDIndex;
680 910
681 911
@@ -686,18 +916,45 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
686 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; 916 ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];
687 917
688#if defined(PDUMP) 918#if defined(PDUMP)
689 PDUMPCOMMENT("Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)", 919 {
690 pMMUHeap->psMMUContext->ui32PDumpMMUContextID, 920 IMG_UINT32 ui32Flags = 0;
691 pMMUHeap->ui32PDBaseIndex, 921
692 ui32Size); 922
693 PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PageTableCount); 923 if( MMU_IsHeapShared(pMMUHeap) )
694 PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PageTableCount); 924 {
925 ui32Flags |= PDUMP_FLAGS_CONTINUOUS;
926 }
927 PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x)",
928 pMMUHeap->psMMUContext->ui32PDumpMMUContextID,
929 pMMUHeap->ui32PDBaseIndex,
930 ui32Size);
931 PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc page table (page count == %08X)", ui32PageTableCount);
932 PDUMPCOMMENTWITHFLAGS(ui32Flags, "Page directory mods (page count == %08X)", ui32PageTableCount);
933 }
695#endif 934#endif
696 935
697 for(i=0; i<ui32PageTableCount; i++) 936 for(i=0; i<ui32PageTableCount; i++)
698 { 937 {
699 if(ppsPTInfoList[i] == IMG_NULL) 938 if(ppsPTInfoList[i] == IMG_NULL)
700 { 939 {
940#if defined(FIX_HW_BRN_31620)
941
942 if (pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i])
943 {
944
945 if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
946 {
947 IMG_UINT32 ui32PDCacheLine = (ui32PDIndex + i) >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
948
949 ppsPTInfoList[i] = pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i];
950 pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = IMG_NULL;
951
952 pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
953 }
954 }
955 else
956 {
957#endif
701 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, 958 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
702 sizeof (MMU_PT_INFO), 959 sizeof (MMU_PT_INFO),
703 (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL, 960 (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL,
@@ -708,8 +965,15 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
708 return IMG_FALSE; 965 return IMG_FALSE;
709 } 966 }
710 OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO)); 967 OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO));
968#if defined(FIX_HW_BRN_31620)
969 }
970#endif
711 } 971 }
712 972#if defined(FIX_HW_BRN_31620)
973
974 if (ppsPTInfoList[i])
975 {
976#endif
713 if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL 977 if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL
714 && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL) 978 && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL)
715 { 979 {
@@ -718,16 +982,43 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
718 IMG_UINT32 *pui32Tmp; 982 IMG_UINT32 *pui32Tmp;
719 IMG_UINT32 j; 983 IMG_UINT32 j;
720#else 984#else
985#if !defined(FIX_HW_BRN_31620)
721 986
722 PVR_ASSERT(pui32PDEntry[i] == 0); 987 PVR_ASSERT(pui32PDEntry[i] == 0);
723#endif 988#endif
724 989#endif
725 if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE) 990 if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE)
726 { 991 {
727 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed")); 992 PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed"));
728 return IMG_FALSE; 993 return IMG_FALSE;
729 } 994 }
995#if defined(FIX_HW_BRN_31620)
996 bFlushSystemCache = IMG_TRUE;
997
998 {
999 IMG_UINT32 ui32PD;
1000 IMG_UINT32 ui32PDCacheLine;
1001 IMG_UINT32 ui32PDBitMaskIndex;
1002 IMG_UINT32 ui32PDBitMaskShift;
1003
1004 ui32PD = ui32PDIndex + i;
1005 ui32PDCacheLine = ui32PD >> BRN31620_PDES_PER_CACHE_LINE_SHIFT;
1006 ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT;
1007 ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK;
1008 ui32ModifiedCachelines[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift;
1009
1010
1011 if ((pMMUHeap->ui32PDBaseIndex + pMMUHeap->ui32PageTableCount) < (ui32PD + 1))
1012 {
1013 pMMUHeap->ui32PageTableCount = (ui32PD + 1) - pMMUHeap->ui32PDBaseIndex;
1014 }
730 1015
1016 if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd))
1017 {
1018 pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++;
1019 }
1020 }
1021#endif
731 switch(pMMUHeap->psDevArena->DevMemHeapType) 1022 switch(pMMUHeap->psDevArena->DevMemHeapType)
732 { 1023 {
733 case DEVICE_MEMORY_HEAP_SHARED : 1024 case DEVICE_MEMORY_HEAP_SHARED :
@@ -746,21 +1037,22 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
746 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) 1037 pui32PDEntry[i] = (sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
747 | pMMUHeap->ui32PDEPageSizeCtrl 1038 | pMMUHeap->ui32PDEPageSizeCtrl
748 | SGX_MMU_PDE_VALID; 1039 | SGX_MMU_PDE_VALID;
749
750 #if defined(PDUMP) 1040 #if defined(PDUMP)
751 1041
752 #if defined(SUPPORT_PDUMP_MULTI_PROCESS) 1042 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
753 if(psMMUContext->bPDumpActive) 1043 if(psMMUContext->bPDumpActive)
754 #endif 1044 #endif
755 { 1045 {
756 1046
757 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); 1047 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
758 } 1048 }
759 #endif 1049 #endif
760
761 1050
762 psMMUContext = psMMUContext->psNext; 1051 psMMUContext = psMMUContext->psNext;
763 } 1052 }
1053#if defined(FIX_HW_BRN_31620)
1054 bSharedPT = IMG_TRUE;
1055#endif
764 break; 1056 break;
765 } 1057 }
766 case DEVICE_MEMORY_HEAP_PERCONTEXT : 1058 case DEVICE_MEMORY_HEAP_PERCONTEXT :
@@ -772,6 +1064,7 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
772 | SGX_MMU_PDE_VALID; 1064 | SGX_MMU_PDE_VALID;
773 1065
774 1066
1067
775 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); 1068 PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
776 break; 1069 break;
777 } 1070 }
@@ -789,17 +1082,112 @@ _DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT
789 1082
790 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); 1083 MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo);
791#endif 1084#endif
1085#if defined(FIX_HW_BRN_31620)
1086
1087 if (((ui32PDIndex + i) < ui32PDRequestStart) || ((ui32PDIndex + i) > ui32PDRequestEnd))
1088 {
1089 pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = ppsPTInfoList[i];
1090 ppsPTInfoList[i] = IMG_NULL;
1091 }
1092#endif
792 } 1093 }
793 else 1094 else
794 { 1095 {
1096#if !defined(FIX_HW_BRN_31620)
795 1097
796 PVR_ASSERT(pui32PDEntry[i] != 0); 1098 PVR_ASSERT(pui32PDEntry[i] != 0);
1099#endif
797 } 1100 }
1101#if defined(FIX_HW_BRN_31620)
1102 }
1103#endif
798 } 1104 }
799 1105
800 #if defined(SGX_FEATURE_SYSTEM_CACHE) 1106 #if defined(SGX_FEATURE_SYSTEM_CACHE)
1107 #if defined(FIX_HW_BRN_31620)
1108
1109 if (bFlushSystemCache)
1110 {
1111 #endif
1112
801 MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo); 1113 MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo);
802 #endif 1114 #endif
1115 #if defined(FIX_HW_BRN_31620)
1116 }
1117
1118
1119 sHighDevVAddr.uiAddr = sHighDevVAddr.uiAddr - 1;
1120
1121
1122 if (bFlushSystemCache)
1123 {
1124 MMU_CONTEXT *psMMUContext;
1125
1126 if (bSharedPT)
1127 {
1128 MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList;
1129
1130 while(psMMUContext)
1131 {
1132 for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
1133 {
1134 psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
1135 }
1136
1137
1138 psMMUContext = psMMUContext->psNext;
1139 }
1140 }
1141 else
1142 {
1143 for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
1144 {
1145 pMMUHeap->psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i];
1146 }
1147 }
1148
1149
1150 psMMUContext = pMMUHeap->psMMUContext;
1151 for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
1152 {
1153 IMG_UINT32 j;
1154
1155 for(j=0;j<BRN31620_CACHE_FLUSH_BITS_SIZE;j++)
1156 {
1157 if (ui32ModifiedCachelines[i] & (1 << j))
1158 {
1159 PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo;
1160 MMU_PT_INFO *psTempPTInfo = IMG_NULL;
1161 IMG_UINT32 *pui32Tmp;
1162
1163 ui32PDIndex = (((i * BRN31620_CACHE_FLUSH_BITS_SIZE) + j) * BRN31620_PDES_PER_CACHE_LINE_SIZE) + BRN31620_DUMMY_PDE_INDEX;
1164
1165
1166 if (psMMUContext->apsPTInfoList[ui32PDIndex])
1167 {
1168 psTempPTInfo = psMMUContext->apsPTInfoList[ui32PDIndex];
1169 }
1170 else
1171 {
1172 psTempPTInfo = psMMUContext->apsPTInfoListSave[ui32PDIndex];
1173 }
1174
1175 PVR_ASSERT(psTempPTInfo != IMG_NULL);
1176
1177 pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr;
1178 PVR_ASSERT(pui32Tmp != IMG_NULL);
1179 pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1180 | SGX_MMU_PTE_DUMMY_PAGE
1181 | SGX_MMU_PTE_READONLY
1182 | SGX_MMU_PTE_VALID;
1183
1184 PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT");
1185 PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1186 }
1187 }
1188 }
1189 }
1190 #endif
803 1191
804 return IMG_TRUE; 1192 return IMG_TRUE;
805} 1193}
@@ -810,6 +1198,7 @@ IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext)
810{ 1198{
811 BM_CONTEXT *pBMContext = hDevMemContext; 1199 BM_CONTEXT *pBMContext = hDevMemContext;
812 PVR_ASSERT(pBMContext); 1200 PVR_ASSERT(pBMContext);
1201
813 return pBMContext->psMMUContext->ui32PDumpMMUContextID; 1202 return pBMContext->psMMUContext->ui32PDumpMMUContextID;
814} 1203}
815 1204
@@ -956,6 +1345,69 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
956 psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); 1345 psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
957 } 1346 }
958#endif 1347#endif
1348#if defined(FIX_HW_BRN_31620)
1349
1350 if(!psDevInfo->pvMMUContextList)
1351 {
1352 IMG_UINT32 j;
1353
1354 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1355 SGX_MMU_PAGE_SIZE,
1356 SGX_MMU_PAGE_SIZE,
1357 &psDevInfo->pvBRN31620DummyPageCpuVAddr,
1358 &psDevInfo->hBRN31620DummyPageOSMemHandle) != PVRSRV_OK)
1359 {
1360 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
1361 return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
1362 }
1363
1364
1365 if(psDevInfo->pvBRN31620DummyPageCpuVAddr)
1366 {
1367 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
1368 psDevInfo->pvBRN31620DummyPageCpuVAddr);
1369 }
1370 else
1371 {
1372 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPageOSMemHandle, 0);
1373 }
1374
1375 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
1376 for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
1377 {
1378 pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
1379 }
1380
1381 psDevInfo->sBRN31620DummyPageDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
1382 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1383
1384
1385 if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1386 SGX_MMU_PAGE_SIZE,
1387 SGX_MMU_PAGE_SIZE,
1388 &psDevInfo->pvBRN31620DummyPTCpuVAddr,
1389 &psDevInfo->hBRN31620DummyPTOSMemHandle) != PVRSRV_OK)
1390 {
1391 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed"));
1392 return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES;
1393 }
1394
1395
1396 if(psDevInfo->pvBRN31620DummyPTCpuVAddr)
1397 {
1398 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
1399 psDevInfo->pvBRN31620DummyPTCpuVAddr);
1400 }
1401 else
1402 {
1403 sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPTOSMemHandle, 0);
1404 }
1405
1406 OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
1407 psDevInfo->sBRN31620DummyPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
1408 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1409 }
1410#endif
959 } 1411 }
960 else 1412 else
961 { 1413 {
@@ -1051,16 +1503,96 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1051 } 1503 }
1052 } 1504 }
1053#endif 1505#endif
1506#if defined(FIX_HW_BRN_31620)
1507
1508 if(!psDevInfo->pvMMUContextList)
1509 {
1510 IMG_UINT32 j;
1511
1512 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
1513 SGX_MMU_PAGE_SIZE,
1514 IMG_NULL,
1515 IMG_NULL,
1516 0,
1517 SGX_MMU_PAGE_SIZE,
1518 0,
1519 &(sSysPAddr.uiAddr))!= IMG_TRUE)
1520 {
1521 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
1522 return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
1523 }
1524
1525
1526 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
1527 psDevInfo->sBRN31620DummyPageDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
1528 psDevInfo->pvBRN31620DummyPageCpuVAddr = OSMapPhysToLin(sCpuPAddr,
1529 SGX_MMU_PAGE_SIZE,
1530 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1531 &psDevInfo->hBRN31620DummyPageOSMemHandle);
1532 if(!psDevInfo->pvBRN31620DummyPageCpuVAddr)
1533 {
1534 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
1535 return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
1536 }
1537
1538 pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr;
1539 for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++)
1540 {
1541 pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE;
1542 }
1543 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1544
1545
1546 if(RA_Alloc(psDeviceNode->psLocalDevMemArena,
1547 SGX_MMU_PAGE_SIZE,
1548 IMG_NULL,
1549 IMG_NULL,
1550 0,
1551 SGX_MMU_PAGE_SIZE,
1552 0,
1553 &(sSysPAddr.uiAddr))!= IMG_TRUE)
1554 {
1555 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed"));
1556 return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY;
1557 }
1558
1559
1560 sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
1561 psDevInfo->sBRN31620DummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
1562 psDevInfo->pvBRN31620DummyPTCpuVAddr = OSMapPhysToLin(sCpuPAddr,
1563 SGX_MMU_PAGE_SIZE,
1564 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1565 &psDevInfo->hBRN31620DummyPTOSMemHandle);
1566
1567 if(!psDevInfo->pvBRN31620DummyPTCpuVAddr)
1568 {
1569 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables"));
1570 return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE;
1571 }
1572
1573 OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE);
1574 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1575 }
1576#endif
1577 }
1578
1579#if defined(FIX_HW_BRN_31620)
1580 if (!psDevInfo->pvMMUContextList)
1581 {
1582
1583 psDevInfo->hKernelMMUContext = psMMUContext;
1584 PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: saving kernel mmu context: %p", psMMUContext));
1054 } 1585 }
1586#endif
1055 1587
1056#if defined(PDUMP) 1588#if defined(PDUMP)
1057#if defined(SUPPORT_PDUMP_MULTI_PROCESS) 1589#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
1058 1590
1059 { 1591 {
1060 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); 1592 PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData();
1061 if(psPerProc == IMG_NULL) 1593 if(psPerProc == IMG_NULL)
1062 { 1594 {
1063 1595
1064 psMMUContext->bPDumpActive = IMG_TRUE; 1596 psMMUContext->bPDumpActive = IMG_TRUE;
1065 } 1597 }
1066 else 1598 else
@@ -1068,7 +1600,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1068 psMMUContext->bPDumpActive = psPerProc->bPDumpActive; 1600 psMMUContext->bPDumpActive = psPerProc->bPDumpActive;
1069 } 1601 }
1070 } 1602 }
1071#endif 1603#endif
1072 1604
1073#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 1605#if IMG_ADDRSPACE_PHYSADDR_BITS == 32
1074 PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)", 1606 PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x%08x)",
@@ -1079,6 +1611,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1079#endif 1611#endif
1080 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG); 1612 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG);
1081#endif 1613#endif
1614
1082#ifdef SUPPORT_SGX_MMU_BYPASS 1615#ifdef SUPPORT_SGX_MMU_BYPASS
1083 EnableHostAccess(psMMUContext); 1616 EnableHostAccess(psMMUContext);
1084#endif 1617#endif
@@ -1093,6 +1626,7 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1093 return PVRSRV_ERROR_INVALID_CPU_ADDR; 1626 return PVRSRV_ERROR_INVALID_CPU_ADDR;
1094 } 1627 }
1095 1628
1629
1096#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) 1630#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1097 1631
1098 for(i=0; i<SGX_MMU_PD_SIZE; i++) 1632 for(i=0; i<SGX_MMU_PD_SIZE; i++)
@@ -1140,13 +1674,71 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1140#if defined(PDUMP) 1674#if defined(PDUMP)
1141#if defined(SUPPORT_PDUMP_MULTI_PROCESS) 1675#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
1142 if(psMMUContext->bPDumpActive) 1676 if(psMMUContext->bPDumpActive)
1143#endif 1677#endif
1144 { 1678 {
1145 1679
1146 PDUMPCOMMENT("Page directory contents"); 1680 PDUMPCOMMENT("Page directory contents");
1147 PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); 1681 PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1148 } 1682 }
1149 1683#endif
1684#if defined(FIX_HW_BRN_31620)
1685 {
1686 IMG_UINT32 i;
1687 IMG_UINT32 ui32PDCount = 0;
1688 IMG_UINT32 *pui32PT;
1689 pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr;
1690
1691 PDUMPCOMMENT("BRN31620 Set up dummy PT");
1692
1693 pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr;
1694 pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)
1695 | SGX_MMU_PTE_DUMMY_PAGE
1696 | SGX_MMU_PTE_READONLY
1697 | SGX_MMU_PTE_VALID;
1698
1699
1700#if defined(PDUMP)
1701
1702 PDUMPCOMMENT("BRN31620 Dump dummy PT contents");
1703 PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1704 PDUMPCOMMENT("BRN31620 Dump dummy page contents");
1705 PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1706
1707
1708 for(i=0;i<SGX_MMU_PT_SIZE;i++)
1709 {
1710 PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, &pui32PT[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1711 }
1712#endif
1713 PDUMPCOMMENT("BRN31620 Dump PDE wire up");
1714
1715 for(i=0;i<SGX_MMU_PD_SIZE;i++)
1716 {
1717 pui32Tmp[i] = 0;
1718
1719 if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX)
1720 {
1721 pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT)
1722 | SGX_MMU_PDE_PAGE_SIZE_4K
1723 | SGX_MMU_PDE_DUMMY_PAGE
1724 | SGX_MMU_PDE_VALID;
1725 }
1726 PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1727 ui32PDCount++;
1728 if (ui32PDCount == BRN31620_PDES_PER_CACHE_LINE_SIZE)
1729 {
1730
1731 ui32PDCount = 0;
1732 }
1733 }
1734
1735
1736
1737 PDUMPCOMMENT("BRN31620 dummy Page table contents");
1738 PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1739 }
1740#endif
1741#if defined(PDUMP)
1150 1742
1151 { 1743 {
1152 PVRSRV_ERROR eError; 1744 PVRSRV_ERROR eError;
@@ -1179,6 +1771,22 @@ MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, I
1179 PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID); 1771 PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID);
1180#endif 1772#endif
1181 1773
1774#if defined(FIX_HW_BRN_31620)
1775 for(i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
1776 {
1777 psMMUContext->ui32PDChangeMask[i] = 0;
1778 }
1779
1780 for(i=0;i<BRN31620_CACHE_FLUSH_SIZE;i++)
1781 {
1782 psMMUContext->ui32PDCacheRangeRefCount[i] = 0;
1783 }
1784
1785 for(i=0;i<SGX_MAX_PD_ENTRIES;i++)
1786 {
1787 psMMUContext->apsPTInfoListSave[i] = IMG_NULL;
1788 }
1789#endif
1182 1790
1183 psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; 1791 psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
1184 psMMUContext->sPDDevPAddr = sPDDevPAddr; 1792 psMMUContext->sPDDevPAddr = sPDDevPAddr;
@@ -1207,7 +1815,7 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
1207 IMG_UINT32 *pui32Tmp, i; 1815 IMG_UINT32 *pui32Tmp, i;
1208 SYS_DATA *psSysData; 1816 SYS_DATA *psSysData;
1209 MMU_CONTEXT **ppsMMUContext; 1817 MMU_CONTEXT **ppsMMUContext;
1210#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) 1818#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined(FIX_HW_BRN_31620)
1211 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo; 1819 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
1212 MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; 1820 MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList;
1213#endif 1821#endif
@@ -1250,11 +1858,32 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
1250 1858
1251 if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL) 1859 if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL)
1252 { 1860 {
1861#if defined(FIX_HW_BRN_31620)
1862 PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo;
1863#endif
1253 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, 1864 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1254 SGX_MMU_PAGE_SIZE, 1865 SGX_MMU_PAGE_SIZE,
1255 psMMUContext->pvPDCpuVAddr, 1866 psMMUContext->pvPDCpuVAddr,
1256 psMMUContext->hPDOSMemHandle); 1867 psMMUContext->hPDOSMemHandle);
1257 1868
1869#if defined(FIX_HW_BRN_31620)
1870
1871 if (!psMMUContextList->psNext)
1872 {
1873 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1874 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1875 SGX_MMU_PAGE_SIZE,
1876 psDevInfo->pvBRN31620DummyPageCpuVAddr,
1877 psDevInfo->hBRN31620DummyPageOSMemHandle);
1878
1879 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1880 OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
1881 SGX_MMU_PAGE_SIZE,
1882 psDevInfo->pvBRN31620DummyPTCpuVAddr,
1883 psDevInfo->hBRN31620DummyPTOSMemHandle);
1884
1885 }
1886#endif
1258#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) 1887#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE)
1259 1888
1260 if(!psMMUContextList->psNext) 1889 if(!psMMUContextList->psNext)
@@ -1319,6 +1948,41 @@ MMU_Finalise (MMU_CONTEXT *psMMUContext)
1319 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); 1948 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1320 } 1949 }
1321#endif 1950#endif
1951#if defined(FIX_HW_BRN_31620)
1952
1953 if(!psMMUContextList->psNext)
1954 {
1955
1956 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1957
1958 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle,
1959 psDevInfo->pvBRN31620DummyPageCpuVAddr);
1960 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1961
1962
1963 OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPageCpuVAddr,
1964 SGX_MMU_PAGE_SIZE,
1965 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1966 psDevInfo->hBRN31620DummyPageOSMemHandle);
1967
1968 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1969
1970
1971 PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
1972
1973 sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle,
1974 psDevInfo->pvBRN31620DummyPTCpuVAddr);
1975 sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr);
1976
1977
1978 OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPTCpuVAddr,
1979 SGX_MMU_PAGE_SIZE,
1980 PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY,
1981 psDevInfo->hBRN31620DummyPTOSMemHandle);
1982
1983 RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE);
1984 }
1985#endif
1322 } 1986 }
1323 1987
1324 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise")); 1988 PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise"));
@@ -1374,7 +2038,7 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
1374 2038
1375 for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++) 2039 for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++)
1376 { 2040 {
1377#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE) 2041#if (!defined(SUPPORT_SGX_MMU_DUMMY_PAGE)) && (!defined(FIX_HW_BRN_31620))
1378 2042
1379 PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0); 2043 PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0);
1380#endif 2044#endif
@@ -1383,12 +2047,12 @@ MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap)
1383 pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry]; 2047 pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry];
1384 if (pui32PDCpuVAddr[ui32PDEntry]) 2048 if (pui32PDCpuVAddr[ui32PDEntry])
1385 { 2049 {
1386 2050
1387 #if defined(PDUMP) 2051 #if defined(PDUMP)
1388 2052
1389 #if defined(SUPPORT_PDUMP_MULTI_PROCESS) 2053 #if defined(SUPPORT_PDUMP_MULTI_PROCESS)
1390 if(psMMUContext->bPDumpActive) 2054 if(psMMUContext->bPDumpActive)
1391 #endif 2055 #endif
1392 { 2056 {
1393 PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); 2057 PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
1394 } 2058 }
@@ -1491,8 +2155,12 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
1491 | SGX_MMU_PTE_VALID; 2155 | SGX_MMU_PTE_VALID;
1492#else 2156#else
1493 2157
2158#if defined(FIX_HW_BRN_31620)
2159 BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
2160#else
1494 pui32Tmp[ui32PTIndex] = 0; 2161 pui32Tmp[ui32PTIndex] = 0;
1495#endif 2162#endif
2163#endif
1496 2164
1497 CheckPT(ppsPTInfoList[0]); 2165 CheckPT(ppsPTInfoList[0]);
1498 } 2166 }
@@ -1501,8 +2169,15 @@ MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap,
1501 2169
1502 if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0) 2170 if (ppsPTInfoList[0] && ppsPTInfoList[0]->ui32ValidPTECount == 0)
1503 { 2171 {
2172#if defined(FIX_HW_BRN_31620)
2173 if (BRN31620FreePageTable(psMMUHeap, ui32PDIndex) == IMG_TRUE)
2174 {
2175 bInvalidateDirectoryCache = IMG_TRUE;
2176 }
2177#else
1504 _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE); 2178 _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE);
1505 bInvalidateDirectoryCache = IMG_TRUE; 2179 bInvalidateDirectoryCache = IMG_TRUE;
2180#endif
1506 } 2181 }
1507 2182
1508 2183
@@ -1536,9 +2211,9 @@ static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap,
1536 MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap; 2211 MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap;
1537 IMG_DEV_VIRTADDR Start; 2212 IMG_DEV_VIRTADDR Start;
1538 2213
1539 Start.uiAddr = ui32Start; 2214 Start.uiAddr = (IMG_UINT32)ui32Start;
1540 2215
1541 MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (ui32End - ui32Start) >> pMMUHeap->ui32PTShift, hUniqueTag); 2216 MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (IMG_UINT32)((ui32End - ui32Start) >> pMMUHeap->ui32PTShift), hUniqueTag);
1542} 2217}
1543 2218
1544MMU_HEAP * 2219MMU_HEAP *
@@ -1618,12 +2293,16 @@ MMU_Create (MMU_CONTEXT *psMMUContext,
1618 pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize; 2293 pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize;
1619 pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize); 2294 pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize);
1620 pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32); 2295 pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32);
2296
1621 2297
1622 if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32)) 2298 if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32))
1623 { 2299 {
1624 pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32); 2300 pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32);
1625 } 2301 }
1626 pMMUHeap->ui32PTECount = pMMUHeap->ui32PTSize >> 2; 2302 pMMUHeap->ui32PTNumEntriesAllocated = pMMUHeap->ui32PTSize >> 2;
2303
2304
2305 pMMUHeap->ui32PTNumEntriesUsable = (IMG_UINT32)(1UL << pMMUHeap->ui32PTBitWidth);
1627 2306
1628 2307
1629 pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift; 2308 pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift;
@@ -1645,7 +2324,7 @@ MMU_Create (MMU_CONTEXT *psMMUContext,
1645 } 2324 }
1646 2325
1647 2326
1648 pMMUHeap->ui32PTETotal = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift; 2327 pMMUHeap->ui32PTETotalUsable = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift;
1649 2328
1650 2329
1651 pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift; 2330 pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift;
@@ -1653,8 +2332,9 @@ MMU_Create (MMU_CONTEXT *psMMUContext,
1653 2332
1654 2333
1655 2334
1656 pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotal + pMMUHeap->ui32PTECount - 1) 2335 pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotalUsable + pMMUHeap->ui32PTNumEntriesUsable - 1)
1657 >> pMMUHeap->ui32PTBitWidth; 2336 >> pMMUHeap->ui32PTBitWidth;
2337 PVR_ASSERT(pMMUHeap->ui32PageTableCount > 0);
1658 2338
1659 2339
1660 pMMUHeap->psVMArena = RA_Create(psDevArena->pszName, 2340 pMMUHeap->psVMArena = RA_Create(psDevArena->pszName,
@@ -1808,7 +2488,7 @@ MMU_Alloc (MMU_HEAP *pMMUHeap,
1808 #endif 2488 #endif
1809 2489
1810 2490
1811 bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, uSize); 2491 bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, (IMG_UINT32)uSize);
1812 2492
1813 #ifdef SUPPORT_SGX_MMU_BYPASS 2493 #ifdef SUPPORT_SGX_MMU_BYPASS
1814 DisableHostAccess(pMMUHeap->psMMUContext); 2494 DisableHostAccess(pMMUHeap->psMMUContext);
@@ -1874,6 +2554,26 @@ MMU_Disable (MMU_HEAP *pMMUHeap)
1874 2554
1875} 2555}
1876 2556
2557#if defined(FIX_HW_BRN_31620)
2558IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask)
2559{
2560 IMG_UINT32 i;
2561
2562 for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++)
2563 {
2564 pui32RangeMask[i] = pMMUContext->ui32PDChangeMask[i];
2565
2566
2567 pMMUContext->ui32PDChangeMask[i] = 0;
2568 }
2569}
2570
2571IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr)
2572{
2573 *psDevPAddr = pMMUContext->sPDDevPAddr;
2574}
2575
2576#endif
1877#if defined(PDUMP) 2577#if defined(PDUMP)
1878static IMG_VOID 2578static IMG_VOID
1879MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, 2579MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
@@ -1891,7 +2591,7 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
1891 IMG_UINT32 ui32PTDumpCount; 2591 IMG_UINT32 ui32PTDumpCount;
1892 2592
1893 2593
1894 ui32NumPTEntries = (uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift; 2594 ui32NumPTEntries = (IMG_UINT32)((uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift);
1895 2595
1896 2596
1897 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; 2597 ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift;
@@ -1910,13 +2610,13 @@ MMU_PDumpPageTables (MMU_HEAP *pMMUHeap,
1910 { 2610 {
1911 MMU_PT_INFO* psPTInfo = *ppsPTInfoList++; 2611 MMU_PT_INFO* psPTInfo = *ppsPTInfoList++;
1912 2612
1913 if(ui32NumPTEntries <= pMMUHeap->ui32PTECount - ui32PTIndex) 2613 if(ui32NumPTEntries <= pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex)
1914 { 2614 {
1915 ui32PTDumpCount = ui32NumPTEntries; 2615 ui32PTDumpCount = ui32NumPTEntries;
1916 } 2616 }
1917 else 2617 else
1918 { 2618 {
1919 ui32PTDumpCount = pMMUHeap->ui32PTECount - ui32PTIndex; 2619 ui32PTDumpCount = pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex;
1920 } 2620 }
1921 2621
1922 if (psPTInfo) 2622 if (psPTInfo)
@@ -2009,7 +2709,12 @@ MMU_MapPage (MMU_HEAP *pMMUHeap,
2009 IMG_UINT32 uTmp = pui32Tmp[ui32Index]; 2709 IMG_UINT32 uTmp = pui32Tmp[ui32Index];
2010 2710
2011 2711
2012 if (uTmp & SGX_MMU_PTE_VALID) 2712#if defined(FIX_HW_BRN_31620)
2713 if ((uTmp & SGX_MMU_PTE_VALID) && ((DevVAddr.uiAddr & BRN31620_PDE_CACHE_FILL_MASK) != BRN31620_DUMMY_PAGE_OFFSET))
2714#else
2715 if ((uTmp & SGX_MMU_PTE_VALID) != 0)
2716#endif
2717
2013 { 2718 {
2014 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u", 2719 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u",
2015 DevVAddr.uiAddr, 2720 DevVAddr.uiAddr,
@@ -2018,8 +2723,9 @@ MMU_MapPage (MMU_HEAP *pMMUHeap,
2018 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp)); 2723 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp));
2019 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr)); 2724 PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x%08X", DevPAddr.uiAddr));
2020 } 2725 }
2021 2726#if !defined(FIX_HW_BRN_31620)
2022 PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0); 2727 PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0);
2728#endif
2023 } 2729 }
2024#endif 2730#endif
2025 2731
@@ -2322,8 +3028,12 @@ MMU_UnmapPages (MMU_HEAP *psMMUHeap,
2322 | SGX_MMU_PTE_VALID; 3028 | SGX_MMU_PTE_VALID;
2323#else 3029#else
2324 3030
3031#if defined(FIX_HW_BRN_31620)
3032 BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]);
3033#else
2325 pui32Tmp[ui32PTIndex] = 0; 3034 pui32Tmp[ui32PTIndex] = 0;
2326#endif 3035#endif
3036#endif
2327 3037
2328 CheckPT(ppsPTInfoList[0]); 3038 CheckPT(ppsPTInfoList[0]);
2329 3039
@@ -2906,9 +3616,9 @@ PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode)
2906 | SGX_MMU_PTE_VALID; 3616 | SGX_MMU_PTE_VALID;
2907 3617
2908 3618
2909 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevID, hPTPageOSMemHandle, 0, pui32PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); 3619 PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPTPageOSMemHandle, 0, pui32PT, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG);
2910 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, hPDPageOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); 3620 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, pui32PD, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);
2911 PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); 3621 PDUMPMEMPTENTRIES(&psDevInfo->sMMUAttrib, hPTPageOSMemHandle, pui32PT, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG);
2912 3622
2913 3623
2914 psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT; 3624 psDevInfo->pui32ExtSystemCacheRegsPT = pui32PT;