--- a/kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp Fri Apr 16 16:24:37 2010 +0300
@@ -444,14 +444,18 @@
return phys;
}
+
TInt ArmMmu::PreparePagesForDMA(TLinAddr aLinAddr, TInt aSize, TPhysAddr* aPhysicalPageList)
//Returns the list of physical pages belonging to the specified memory space.
//Checks these pages belong to a chunk marked as being trusted.
-//Locks these pages so they can not be moved by e.g. ram defragmenation.
+//Locks these pages so they can not be moved by e.g. ram defragmentation.
{
SPageInfo* pi = NULL;
DChunk* chunk = NULL;
TInt err = KErrNone;
+
+ __NK_ASSERT_DEBUG(MM::MaxPagesInOneGo == 32); // Needs to be a power of 2.
+ TUint flashMask = MM::MaxPagesInOneGo - 1;
__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::PreparePagesForDMA %08x+%08x, asid=%d",aLinAddr,aSize));
@@ -474,41 +478,64 @@
pagesLeft -= pagesLeftInChunk;
- TPte* pt = SafePageTableFromPde(*pdePtr++);
- if(!pt) { err = KErrNotFound; goto fail; }// Cannot get page table.
-
- pt += pageIndex;
+ TPte* pPte = SafePageTableFromPde(*pdePtr++);
+ if(!pPte)
+ {// Cannot get page table.
+ err = KErrNotFound;
+ goto fail;
+ }
+
+ pPte += pageIndex;
for(;pagesLeftInChunk--;)
{
- TPhysAddr phys = (*pt++ & KPteSmallPageAddrMask);
+ TPhysAddr phys = (*pPte++ & KPteSmallPageAddrMask);
pi = SPageInfo::SafeFromPhysAddr(phys);
- if(!pi) { err = KErrNotFound; goto fail; }// Invalid address
-
+ if(!pi)
+ {// Invalid address
+ err = KErrNotFound;
+ goto fail;
+ }
+
__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: PA:%x T:%x S:%x O:%x C:%x",phys, pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
- if (chunk==NULL)
+ if (chunk == NULL)
{//This is the first page. Check 'trusted' bit.
if (pi->Type()!= SPageInfo::EChunk)
- { err = KErrAccessDenied; goto fail; }// The first page do not belong to chunk.
+ {// The first page does not belong to a chunk.
+ err = KErrAccessDenied;
+ goto fail;
+ }
chunk = (DChunk*)pi->Owner();
- if ( (chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk)== 0) )
- { err = KErrAccessDenied; goto fail; } // Not a trusted chunk
+ if ((chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk) == 0))
+ {// Not a trusted chunk
+ err = KErrAccessDenied;
+ goto fail;
+ }
}
pi->Lock();
*pageList++ = phys;
- if ( (++pagesInList&127) == 0) //release system lock temporarily on every 512K
+
+ if(!(++pagesInList & flashMask))
+ {
NKern::FlashSystem();
+ }
}
pageIndex = 0;
}
- if (pi->Type()!= SPageInfo::EChunk)
- { err = KErrAccessDenied; goto fail; }// The last page do not belong to chunk.
+ if (pi->Type() != SPageInfo::EChunk)
+ {// The last page does not belong to a chunk.
+ err = KErrAccessDenied;
+ goto fail;
+ }
if (chunk && (chunk != (DChunk*)pi->Owner()))
- { err = KErrArgument; goto fail; }//The first & the last page do not belong to the same chunk.
+ {//The first & the last page do not belong to the same chunk.
+ err = KErrArgument;
+ goto fail;
+ }
NKern::UnlockSystem();
MmuBase::Signal();
@@ -522,6 +549,7 @@
return err;
}
+
TInt ArmMmu::ReleasePagesFromDMA(TPhysAddr* aPhysicalPageList, TInt aPageCount)
// Unlocks physical pages.
// @param aPhysicalPageList - points to the list of physical pages that should be released.
@@ -530,6 +558,7 @@
NKern::LockSystem();
__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::ReleasePagesFromDMA count:%d",aPageCount));
+ TUint flashMask = MM::MaxPagesInOneGo - 1;
while (aPageCount--)
{
SPageInfo* pi = SPageInfo::SafeFromPhysAddr(*aPhysicalPageList++);
@@ -540,12 +569,18 @@
}
__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: T:%x S:%x O:%x C:%x",pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
pi->Unlock();
+
+ if(!(aPageCount & flashMask))
+ {
+ NKern::FlashSystem();
+ }
}
NKern::UnlockSystem();
return KErrNone;
}
+
void ArmMmu::Init1()
{
__KTRACE_OPT2(KBOOT,KMMU,Kern::Printf("ArmMmu::Init1"));