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; |