Update contrib.
1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
26 TInt M::RamDefragFault(TAny* /*aExceptionInfo*/)
27 {// Defag faults are handled by Mmu::HandlePageFault() on the flexible memory model.
32 EXPORT_C TInt Epoc::MovePhysicalPage(TPhysAddr aOld, TPhysAddr& aNew, TRamDefragPageToMove aPageToMove)
34 CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::MovePhysicalPage");
35 __KTRACE_OPT(KMMU,Kern::Printf("Epoc::MovePhysicalPage() old=%08x pageToMove=%d",aOld,aPageToMove));
36 // Mark aNew as invalid if a page is moved then this will be updated.
37 // However, if the page couldn't be moved or is discarded then it must be invalid.
38 aNew = KPhysAddrInvalid;
40 TInt r = KErrNotFound;
44 case ERamDefragPage_Physical :
47 case ERamDefragPage_PageTable :
49 // Assume aOld is a linear address in current thread and get the physical
50 // address of the page table that maps it and move that.
51 TLinAddr linAddr = (TLinAddr) aOld;
52 DMemModelThread* thread = (DMemModelThread*)TheCurrentThread;
53 // Get the os asid of current thread's process so no need to open reference on it.
54 TUint osAsid = ((DMemModelProcess*)thread->iOwningProcess)->OsAsid();
55 TUint offsetInMapping;
56 TUint mapInstanceCount;
57 DMemoryMapping* mapping = MM::FindMappingInAddressSpace(osAsid,linAddr,1,offsetInMapping,mapInstanceCount);
61 TUint memoryIndex = (offsetInMapping >> KPageShift)+ mapping->iStartIndex;
62 TPte* pte = mapping->FindPageTable(linAddr, memoryIndex);
63 if (mapInstanceCount != mapping->MapInstanceCount() || !pte)
69 TPhysAddr physAddr = TheMmu.LinearToPhysical((TLinAddr)pte, KKernelOsAsid);
70 __NK_ASSERT_DEBUG(physAddr != KPhysAddrInvalid);
71 aOld = physAddr; // Have physical address of page table page so move it.
77 case ERamDefragPage_PageTableInfo :
79 // Assume aOld is a linear address in current thread and get physical
80 // address of the page table info of the page table that maps it
82 TLinAddr linAddr = (TLinAddr) aOld;
83 DMemModelThread* thread = (DMemModelThread*)TheCurrentThread;
84 // Get the os asid of current thread's process so no need to open reference on it.
85 TUint osAsid = ((DMemModelProcess*)thread->iOwningProcess)->OsAsid();
86 TUint offsetInMapping;
87 TUint mapInstanceCount;
88 DMemoryMapping* mapping = MM::FindMappingInAddressSpace(osAsid,linAddr,1,offsetInMapping,mapInstanceCount);
92 TUint memoryIndex = (offsetInMapping >> KPageShift)+ mapping->iStartIndex;
93 TPte* pte = mapping->FindPageTable(linAddr, memoryIndex);
94 if (mapInstanceCount != mapping->MapInstanceCount() || !pte)
101 SPageTableInfo* pti = SPageTableInfo::FromPtPtr(pte);
102 TPhysAddr physAddr = TheMmu.LinearToPhysical((TLinAddr)pti, KKernelOsAsid);
103 __NK_ASSERT_DEBUG(physAddr != KPhysAddrInvalid);
104 aOld = physAddr; // Have physical address of page table info page so move it.
111 r = KErrNotSupported;
115 RamAllocLock::Lock();
117 // Move the page to any RAM zone.
118 r = M::MovePage(aOld, aNew, KRamZoneInvalidId, EFalse);
120 RamAllocLock::Unlock();
125 TInt M::MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)
129 // get memory object corresponding to the page...
130 DMemoryObject* memory = 0;
132 SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aOld&~KPageMask);
135 if (pi->PagedState() != SPageInfo::EUnpaged)
136 {// The page is paged so let the pager handle it.
137 return ThePager.DiscardPage(pi, aBlockZoneId, aBlockRest);
139 if (pi->Type()==SPageInfo::EManaged)
140 memory = pi->Owner();
144 // Note, whilst we hold the RamAllocLock the page can't change it's use
145 // and we can safely assume that it still belongs to the memory object
146 // at a fixed page index.
147 // Also, as memory objects can't be destroyed whilst they still own pages
148 // we can safely access this object without taking an explicit referernce,
149 // i.e. we don't need to Open() the memory object.
151 {// page info for aOld not found so aOld is not a RAM page...
156 // page does not have a memory manager, so we can't move it...
157 r = KErrNotSupported;
162 r = memory->iManager->MovePage(memory, pi, aNew, aBlockZoneId, aBlockRest);