kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
branchRCL_3
changeset 22 2f92ad2dc5db
parent 19 4a8fed1c0ef6
child 24 41f0cfe18c80
equal deleted inserted replaced
21:e7d2d738d3c2 22:2f92ad2dc5db
    84 					+(4+KPtClusterSize-1)/KPtClusterSize		// page table pages
    84 					+(4+KPtClusterSize-1)/KPtClusterSize		// page table pages
    85 					+(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage;	// page table info pages
    85 					+(4+KPageTableInfosPerPage-1)/KPageTableInfosPerPage;	// page table info pages
    86 
    86 
    87 #elif defined(__CPU_X86)
    87 #elif defined(__CPU_X86)
    88 
    88 
    89 /*	Need at least 6 mapped pages to guarantee to be able to execute all ARM instructions,
    89 /*	Need at least 6 mapped pages to guarantee to be able to execute all X86 instructions,
    90 	plus enough pages for 6 page tables to map those pages, plus enough pages for the
    90 	plus enough pages for 6 page tables to map those pages, plus enough pages for the
    91 	page table info structures of those page tables.
    91 	page table info structures of those page tables.
    92 	(Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all
    92 	(Worst case is (?) a MOV [X],[Y] instruction with instruction, 'X' and 'Y' all
    93 	straddling chunk boundaries.)
    93 	straddling chunk boundaries.)
    94 */
    94 */
   206 		// Allocate a single page
   206 		// Allocate a single page
   207 		TPhysAddr pagePhys;
   207 		TPhysAddr pagePhys;
   208 		TInt r = m.AllocRam(&pagePhys, 1, 
   208 		TInt r = m.AllocRam(&pagePhys, 1, 
   209 							(Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), 
   209 							(Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe|Mmu::EAllocNoPagerReclaim), 
   210 							EPageDiscard);
   210 							EPageDiscard);
   211 		if(r!=KErrNone)
   211 		__NK_ASSERT_ALWAYS(r == KErrNone);
   212 			__NK_ASSERT_ALWAYS(0);
       
   213 		MmuLock::Lock();
   212 		MmuLock::Lock();
   214 		AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys));
   213 		AddAsFreePage(SPageInfo::FromPhysAddr(pagePhys));
   215 		MmuLock::Unlock();
   214 		MmuLock::Unlock();
   216 		}
   215 		}
   217 	RamAllocLock::Unlock();
   216 	RamAllocLock::Unlock();
   224 #endif
   223 #endif
   225 	}
   224 	}
   226 
   225 
   227 
   226 
   228 #ifdef _DEBUG
   227 #ifdef _DEBUG
       
   228 #ifdef FMM_PAGER_CHECK_LISTS
       
   229 TBool CheckList(SDblQueLink* aHead, TUint aCount)
       
   230 	{
       
   231 	SDblQueLink* link = aHead;
       
   232 	while(aCount--)
       
   233 		{
       
   234 		link = link->iNext;
       
   235 		if(link == aHead)
       
   236 			return EFalse;
       
   237 		}
       
   238 	link = link->iNext;
       
   239 	if(link != aHead)
       
   240 		return EFalse;
       
   241 	return ETrue;
       
   242 	}
       
   243 #endif // #ifdef FMM_PAGER_CHECK_LISTS
       
   244 
   229 TBool DPager::CheckLists()
   245 TBool DPager::CheckLists()
   230 	{
   246 	{
   231 #if 0
   247 #ifdef FMM_PAGER_CHECK_LISTS
   232 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   248 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   233 	SDblQueLink* head = &iOldList.iA;
   249 	if (!CheckList(&iOldList.iA, iOldCount))
   234 	TInt n = iOldCount;
   250 		return EFalse;
   235 	SDblQueLink* link = head;
   251 	if (!CheckList(&iYoungList.iA, iYoungCount))
   236 	while(n--)
   252 		return EFalse;
   237 		{
   253 
   238 		link = link->iNext;
   254 #ifdef _USE_OLDEST_LISTS
   239 		if(link==head)
   255 	if (!CheckList(&iOldestCleanList.iA, iOldestCleanCount))
   240 			return false;
   256 		return EFalse;
   241 		}
   257 	if (!CheckList(&iOldestDirtyList.iA, iOldestDirtyCount))
   242 	link = link->iNext;
   258 		return EFalse;
   243 	if(link!=head)
   259 	TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d", iYoungCount, iOldCount, 
   244 		return false;
   260 			iOldestCleanCount, iOldestDirtyCount, iNumberOfFreePages));
   245 
   261 #else
   246 	head = &iYoungList.iA;
   262 	TRACEP(("DP: y=%d o=%d f=%d", iYoungCount, iOldCount, iNumberOfFreePages));
   247 	n = iYoungCount;
   263 #endif //#ifdef _USE_OLDEST_LISTS
   248 	link = head;
   264 	TraceCounts();
   249 	while(n--)
   265 #endif // #ifdef FMM_PAGER_CHECK_LISTS
   250 		{
       
   251 		link = link->iNext;
       
   252 		if(link==head)
       
   253 			return false;
       
   254 		}
       
   255 	link = link->iNext;
       
   256 	if(link!=head)
       
   257 		return false;
       
   258 
       
   259 //	TRACEP(("DP: y=%d o=%d f=%d",iYoungCount,iOldCount,iNumberOfFreePages));
       
   260 #endif
       
   261 //	TraceCounts();
       
   262 	return true;
   266 	return true;
   263 	}
   267 	}
   264 
   268 
   265 void DPager::TraceCounts()
   269 void DPager::TraceCounts()
   266 	{
   270 	{
       
   271 #ifdef _USE_OLDEST_LISTS
       
   272 	TRACEP(("DP: y=%d o=%d oc=%d od=%d f=%d min=%d max=%d ml=%d res=%d",
       
   273 		iYoungCount, iOldCount, iOldestCleanCount, iOldestDirtyCount, 
       
   274 		iNumberOfFreePages, iMinimumPageCount, iMaximumPageCount,
       
   275 		iMinimumPageLimit, iReservePageCount));
       
   276 #else
   267 	TRACEP(("DP: y=%d o=%d f=%d min=%d max=%d ml=%d res=%d",
   277 	TRACEP(("DP: y=%d o=%d f=%d min=%d max=%d ml=%d res=%d",
   268 		iYoungCount,iOldCount,iNumberOfFreePages,iMinimumPageCount,
   278 		iYoungCount, iOldCount, iNumberOfFreePages, iMinimumPageCount,
   269 		iMaximumPageCount,iMinimumPageLimit,iReservePageCount));
   279 		iMaximumPageCount, iMinimumPageLimit, iReservePageCount));
   270 	}
   280 #endif //#ifdef _USE_OLDEST_LISTS
   271 
   281 	}
   272 #endif
   282 #endif //#ifdef _DEBUG
   273 
   283 
   274 
   284 
   275 TBool DPager::HaveTooManyPages()
   285 TBool DPager::HaveTooManyPages()
   276 	{
   286 	{
   277 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
   287 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
  1738 		aMinimumPageCount = iMinimumPageLimit+iReservePageCount;
  1748 		aMinimumPageCount = iMinimumPageLimit+iReservePageCount;
  1739 	if(aMaximumPageCount<aMinimumPageCount)
  1749 	if(aMaximumPageCount<aMinimumPageCount)
  1740 		aMaximumPageCount=aMinimumPageCount;
  1750 		aMaximumPageCount=aMinimumPageCount;
  1741 
  1751 
  1742 	// Increase iMaximumPageCount?
  1752 	// Increase iMaximumPageCount?
  1743 	TInt extra = aMaximumPageCount-iMaximumPageCount;
  1753 	if(aMaximumPageCount > iMaximumPageCount)
  1744 	if(extra>0)
  1754 		iMaximumPageCount = aMaximumPageCount;
  1745 		iMaximumPageCount += extra;
       
  1746 
  1755 
  1747 	// Reduce iMinimumPageCount?
  1756 	// Reduce iMinimumPageCount?
  1748 	TInt spare = iMinimumPageCount-aMinimumPageCount;
  1757 	TInt spare = iMinimumPageCount-aMinimumPageCount;
  1749 	if(spare>0)
  1758 	if(spare>0)
  1750 		{
  1759 		{
  2156 	DMemoryObject* memory = iUseRegionMemory;
  2165 	DMemoryObject* memory = iUseRegionMemory;
  2157 	TUint index = iUseRegionIndex;
  2166 	TUint index = iUseRegionIndex;
  2158 	TUint count = iUseRegionCount;
  2167 	TUint count = iUseRegionCount;
  2159 	// note, this comparison would fail if either region includes page number KMaxTUint,
  2168 	// note, this comparison would fail if either region includes page number KMaxTUint,
  2160 	// but it isn't possible to create a memory object which is > KMaxTUint pages...
  2169 	// but it isn't possible to create a memory object which is > KMaxTUint pages...
  2161 	return memory == aMemory && index+count > aIndex && index < aIndex+aCount;
  2170 	return (memory == aMemory) && ((index + count) > aIndex) && (index < (aIndex + aCount));
  2162 	}
  2171 	}
  2163 
  2172 
  2164 
  2173 
  2165 TLinAddr DPagingRequest::MapPages(TUint aColour, TUint aCount, TPhysAddr* aPages)
  2174 TLinAddr DPagingRequest::MapPages(TUint aColour, TUint aCount, TPhysAddr* aPages)
  2166 	{
  2175 	{
  2522 
  2531 
  2523 
  2532 
  2524 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize)
  2533 EXPORT_C TInt DDemandPagingLock::Lock(DThread* aThread, TLinAddr aStart, TInt aSize)
  2525 	{
  2534 	{
  2526 //	TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize));
  2535 //	TRACEP(("DDemandPagingLock[0x%08x]::Lock(0x%08x,0x%08x,0x%08x)",this,aThread,aStart,aSize));
  2527 	if(iLockedPageCount)
  2536 	__NK_ASSERT_ALWAYS(!iLockedPageCount); // lock already used
  2528 		__NK_ASSERT_ALWAYS(0); // lock already used
       
  2529 
  2537 
  2530 	// calculate the number of pages that need to be locked...
  2538 	// calculate the number of pages that need to be locked...
  2531 	TUint mask=KPageMask;
  2539 	TUint mask=KPageMask;
  2532 	TUint offset=aStart&mask;
  2540 	TUint offset=aStart&mask;
  2533 	TInt numPages = (aSize+offset+mask)>>KPageShift;
  2541 	TInt numPages = (aSize+offset+mask)>>KPageShift;
  2534 	if(numPages>iMaxPageCount)
  2542 
  2535 		__NK_ASSERT_ALWAYS(0);
  2543 	// Should never be asked to lock more pages than are allocated to this object.
       
  2544 	__NK_ASSERT_ALWAYS(numPages <= iMaxPageCount);
  2536 
  2545 
  2537 	NKern::ThreadEnterCS();
  2546 	NKern::ThreadEnterCS();
  2538 
  2547 
  2539 	// find mapping which covers the specified region...
  2548 	// find mapping which covers the specified region...
  2540 	TUint offsetInMapping;
  2549 	TUint offsetInMapping;