diff -r 2d65c2f76d7b -r 947f0dc9f7a8 kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp --- 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"));