diff -r 538db54a451d -r 5d2844f35677 kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp --- a/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp Mon Jan 18 21:31:10 2010 +0200 +++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp Tue Jan 26 13:13:38 2010 +0200 @@ -63,6 +63,12 @@ DMemoryMapping::~DMemoryMapping() { TRACE(("DMemoryMapping[0x%08x]::~DMemoryMapping()",this)); + Destruct(); + } + + +void DMemoryMapping::Destruct() + { __NK_ASSERT_DEBUG(!IsAttached()); // remove from address space... @@ -1258,6 +1264,74 @@ } +// +// DKernelPinMapping +// +DKernelPinMapping::DKernelPinMapping() + // : iReservePages(0) // Allocated on the kernel heap so will already be 0. + { + Flags() |= EPhysicalPinningMapping | EPinned; + } + + +TInt DKernelPinMapping::Construct(TUint aReserveMaxSize) + { + TInt r = KErrNone; + if (aReserveMaxSize) + { + // Should not call Construct() on a mapping that has already reserved resources. + __NK_ASSERT_DEBUG(!iReservePages); + r = DFineMapping::Construct(EMemoryAttributeStandard, + EMappingCreateReserveAllResources, + KKernelOsAsid, + 0, + aReserveMaxSize, + 0); + if (r == KErrNone) + iReservePages = aReserveMaxSize >> KPageShift; + } + return r; + } + + +TInt DKernelPinMapping::MapAndPin(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TMappingPermissions aPermissions) + { + if (IsAttached()) + { + return KErrInUse; + } + + if (!iReservePages) + { + TInt r = DFineMapping::Construct( EMemoryAttributeStandard, + EMappingCreateDefault, + KKernelOsAsid, + 0, + aCount, + 0); + if (r != KErrNone) + return r; + } + // Map the memory, this will pin it first then map it. + TInt r = DFineMapping::Map(aMemory, aIndex, aCount, aPermissions); + + if (r != KErrNone && !iReservePages) + {// Reset this mapping object so it can be reused but has freed its address space. + DMemoryMapping::Destruct(); + } + return r; + } + + +void DKernelPinMapping::UnmapAndUnpin() + { + DFineMapping::Unmap(); + if (!iReservePages) + {// Reset this mapping object so it can be reused but has freed its address space. + DMemoryMapping::Destruct(); + } + } + // // DPhysicalPinMapping @@ -1269,41 +1343,6 @@ } -TInt DPhysicalPinMapping::PhysAddr(TUint aIndex, TUint aCount, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList) - { - __NK_ASSERT_ALWAYS(IsAttached()); - - __NK_ASSERT_ALWAYS(TUint(aIndex+aCount)>aIndex && TUint(aIndex+aCount)<=iSizeInPages); - aIndex += iStartIndex; - - DCoarseMemory* memory = (DCoarseMemory*)Memory(true); // safe because we should only be called whilst memory is Pinned - TInt r = memory->PhysAddr(aIndex,aCount,aPhysicalAddress,aPhysicalPageList); - if(r!=KErrNone) - return r; - - if(memory->IsDemandPaged() && !IsReadOnly()) - { - // the memory is demand paged and writeable so we need to mark it as dirty - // as we have to assume that the memory will be modified via the physical - // addresses we return... - MmuLock::Lock(); - TPhysAddr* pages = aPhysicalPageList; - TUint count = aCount; - while(count) - { - SPageInfo* pi = SPageInfo::FromPhysAddr(*(pages++)); - pi->SetDirty(); - if((count&(KMaxPageInfoUpdatesInOneGo-1))==0) - MmuLock::Flash(); // flash lock every KMaxPageInfoUpdatesInOneGo iterations of the loop - --count; - } - MmuLock::Unlock(); - } - - return KErrNone; - } - - TInt DPhysicalPinMapping::Pin(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TMappingPermissions aPermissions) { PteType() = Mmu::PteType(aPermissions,true); @@ -1714,6 +1753,41 @@ } +TInt DMemoryMappingBase::PhysAddr(TUint aIndex, TUint aCount, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList) + { + __NK_ASSERT_ALWAYS(IsAttached() && IsPhysicalPinning()); + + __NK_ASSERT_ALWAYS(TUint(aIndex+aCount)>aIndex && TUint(aIndex+aCount)<=iSizeInPages); + aIndex += iStartIndex; + + DCoarseMemory* memory = (DCoarseMemory*)Memory(true); // safe because we should only be called whilst memory is Pinned + TInt r = memory->PhysAddr(aIndex,aCount,aPhysicalAddress,aPhysicalPageList); + if(r!=KErrNone) + return r; + + if(memory->IsDemandPaged() && !IsReadOnly()) + { + // the memory is demand paged and writeable so we need to mark it as dirty + // as we have to assume that the memory will be modified via the physical + // addresses we return... + MmuLock::Lock(); + TPhysAddr* pages = aPhysicalPageList; + TUint count = aCount; + while(count) + { + SPageInfo* pi = SPageInfo::FromPhysAddr(*(pages++)); + pi->SetDirty(); + if((count&(KMaxPageInfoUpdatesInOneGo-1))==0) + MmuLock::Flash(); // flash lock every KMaxPageInfoUpdatesInOneGo iterations of the loop + --count; + } + MmuLock::Unlock(); + } + + return KErrNone; + } + + // // Debug