731 // TRACE(("%O mapping=0x%08x",TheCurrentThread,mapping)); |
731 // TRACE(("%O mapping=0x%08x",TheCurrentThread,mapping)); |
732 TInt r = KErrNotFound; |
732 TInt r = KErrNotFound; |
733 |
733 |
734 if(mapping) |
734 if(mapping) |
735 { |
735 { |
736 // Pinning mappings should not be found from within an address space. |
|
737 __NK_ASSERT_DEBUG(!mapping->IsPinned()); |
|
738 MmuLock::Lock(); |
736 MmuLock::Lock(); |
739 |
737 |
740 // check if we need to process page fault... |
738 // check if we need to process page fault... |
741 if(!Mmu::CheckPteTypePermissions(mapping->PteType(),aAccessPermissions) || |
739 if(!Mmu::CheckPteTypePermissions(mapping->PteType(),aAccessPermissions) || |
742 mapInstanceCount != mapping->MapInstanceCount()) |
740 mapInstanceCount != mapping->MapInstanceCount()) |
2159 return aPinObject != NULL ? KErrNone : KErrNoMemory; |
2161 return aPinObject != NULL ? KErrNone : KErrNoMemory; |
2160 } |
2162 } |
2161 |
2163 |
2162 TInt M::PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr aStart, TUint aSize, DThread* aThread) |
2164 TInt M::PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr aStart, TUint aSize, DThread* aThread) |
2163 { |
2165 { |
2164 NKern::ThreadEnterCS(); |
2166 __ASSERT_CRITICAL; |
2165 TUint offsetInMapping; |
2167 TUint offsetInMapping; |
2166 TUint mapInstanceCount; |
2168 TUint mapInstanceCount; |
2167 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)aThread, |
2169 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)aThread, |
2168 aStart, |
2170 aStart, |
2169 aSize, |
2171 aSize, |
2203 mapping, mapInstanceCount); |
2205 mapping, mapInstanceCount); |
2204 memory->Close(); |
2206 memory->Close(); |
2205 } |
2207 } |
2206 } |
2208 } |
2207 mapping->Close(); |
2209 mapping->Close(); |
2208 } |
2210 } |
2209 NKern::ThreadLeaveCS(); |
|
2210 |
|
2211 return r; |
2211 return r; |
2212 } |
2212 } |
2213 |
2213 |
2214 TInt M::CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr aStart, TUint aSize) |
2214 TInt M::CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr aStart, TUint aSize) |
2215 { |
2215 { |
|
2216 __ASSERT_CRITICAL; |
2216 aPinObject = 0; |
2217 aPinObject = 0; |
2217 NKern::ThreadEnterCS(); |
|
2218 TUint offsetInMapping; |
2218 TUint offsetInMapping; |
2219 TUint mapInstanceCount; |
2219 TUint mapInstanceCount; |
2220 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)&Kern::CurrentThread(), |
2220 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)&Kern::CurrentThread(), |
2221 aStart, |
2221 aStart, |
2222 aSize, |
2222 aSize, |
2286 mapping->Unpin(); |
2284 mapping->Unpin(); |
2287 mapping->AsyncClose(); |
2285 mapping->AsyncClose(); |
2288 } |
2286 } |
2289 } |
2287 } |
2290 |
2288 |
|
2289 // |
|
2290 // Physical pinning |
|
2291 // |
|
2292 |
2291 TInt M::CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject) |
2293 TInt M::CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject) |
2292 { |
2294 { |
2293 aPinObject = (TPhysicalPinObject*)new DPhysicalPinMapping; |
2295 aPinObject = (TPhysicalPinObject*)new DPhysicalPinMapping; |
2294 return aPinObject != NULL ? KErrNone : KErrNoMemory; |
2296 return aPinObject != NULL ? KErrNone : KErrNoMemory; |
2295 } |
2297 } |
2296 |
2298 |
2297 // |
|
2298 // Physical pinning |
|
2299 // |
|
2300 |
|
2301 TInt M::PinPhysicalMemory(TPhysicalPinObject* aPinObject, TLinAddr aStart, TUint aSize, TBool aReadOnly, |
2299 TInt M::PinPhysicalMemory(TPhysicalPinObject* aPinObject, TLinAddr aStart, TUint aSize, TBool aReadOnly, |
2302 TPhysAddr& aAddress, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour, DThread* aThread) |
2300 TPhysAddr& aAddress, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour, DThread* aThread) |
2303 { |
2301 { |
2304 NKern::ThreadEnterCS(); |
2302 __ASSERT_CRITICAL; |
2305 TUint offsetInMapping; |
2303 TUint offsetInMapping; |
2306 TUint mapInstanceCount; |
2304 TUint mapInstanceCount; |
2307 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)aThread, |
2305 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)aThread, |
2308 aStart, |
2306 aStart, |
2309 aSize, |
2307 aSize, |
2366 mapping->Unpin(); |
2363 mapping->Unpin(); |
2367 mapping->AsyncClose(); |
2364 mapping->AsyncClose(); |
2368 } |
2365 } |
2369 } |
2366 } |
2370 |
2367 |
|
2368 |
|
2369 // |
|
2370 // Kernel map and pin. |
|
2371 // |
|
2372 |
|
2373 TInt M::CreateKernelMapObject(TKernelMapObject*& aMapObject, TUint aMaxReserveSize) |
|
2374 { |
|
2375 DKernelPinMapping* pinObject = new DKernelPinMapping(); |
|
2376 aMapObject = (TKernelMapObject*) pinObject; |
|
2377 if (pinObject == NULL) |
|
2378 { |
|
2379 return KErrNoMemory; |
|
2380 } |
|
2381 // Ensure we reserve enough bytes for all possible alignments of the start and |
|
2382 // end of the region to map. |
|
2383 TUint reserveBytes = aMaxReserveSize? ((aMaxReserveSize + KPageMask) & ~KPageMask) + KPageSize : 0; |
|
2384 TInt r = pinObject->Construct(reserveBytes); |
|
2385 if (r != KErrNone) |
|
2386 {// Failed so delete the kernel mapping object. |
|
2387 pinObject->Close(); |
|
2388 aMapObject = NULL; |
|
2389 } |
|
2390 return r; |
|
2391 } |
|
2392 |
|
2393 |
|
2394 TInt M::MapAndPinMemory(TKernelMapObject* aMapObject, DThread* aThread, TLinAddr aStart, |
|
2395 TUint aSize, TUint aMapAttributes, TLinAddr& aKernelAddr, TPhysAddr* aPages) |
|
2396 { |
|
2397 __ASSERT_CRITICAL; |
|
2398 TUint offsetInMapping; |
|
2399 TUint mapInstanceCount; |
|
2400 DMemoryMapping* mapping = MM::FindMappingInThread( (DMemModelThread*)aThread, |
|
2401 aStart, |
|
2402 aSize, |
|
2403 offsetInMapping, |
|
2404 mapInstanceCount); |
|
2405 TInt r = KErrBadDescriptor; |
|
2406 if (mapping) |
|
2407 { |
|
2408 DKernelPinMapping* kernelMap = (DKernelPinMapping*)aMapObject; |
|
2409 TInt count = (((aStart + aSize + KPageMask) & ~KPageMask) - (aStart & ~KPageMask)) >> KPageShift; |
|
2410 if (kernelMap->iReservePages && kernelMap->iReservePages < count) |
|
2411 { |
|
2412 mapping->Close(); |
|
2413 return KErrArgument; |
|
2414 } |
|
2415 |
|
2416 MmuLock::Lock(); |
|
2417 DMemoryObject* memory = mapping->Memory(); |
|
2418 if (mapInstanceCount == mapping->MapInstanceCount() && memory) |
|
2419 { |
|
2420 memory->Open(); |
|
2421 MmuLock::Unlock(); |
|
2422 |
|
2423 TUint startInMemory = (offsetInMapping >> KPageShift) + mapping->iStartIndex; |
|
2424 TBool readOnly = aMapAttributes & Kern::EKernelMap_ReadOnly; |
|
2425 TMappingPermissions permissions = readOnly ? ESupervisorReadOnly : ESupervisorReadWrite; |
|
2426 r = kernelMap->MapAndPin(memory, startInMemory, count, permissions); |
|
2427 if (r == KErrNone) |
|
2428 { |
|
2429 __NK_ASSERT_DEBUG(!kernelMap->IsUserMapping()); |
|
2430 aKernelAddr = kernelMap->Base(); |
|
2431 TPhysAddr contigAddr; // Ignore this value as aPages will be populated |
|
2432 // whether the memory is contiguous or not. |
|
2433 r = kernelMap->PhysAddr(0, count, contigAddr, aPages); |
|
2434 if (r>=KErrNone) |
|
2435 { |
|
2436 r = KErrNone; //Do not report discontiguous memory in return value. |
|
2437 } |
|
2438 else |
|
2439 { |
|
2440 UnmapAndUnpinMemory((TKernelMapObject*)kernelMap); |
|
2441 } |
|
2442 } |
|
2443 memory->Close(); |
|
2444 } |
|
2445 else // mapping has been reused or no memory... |
|
2446 { |
|
2447 MmuLock::Unlock(); |
|
2448 } |
|
2449 mapping->Close(); |
|
2450 } |
|
2451 return r; |
|
2452 } |
|
2453 |
|
2454 |
|
2455 void M::UnmapAndUnpinMemory(TKernelMapObject* aMapObject) |
|
2456 { |
|
2457 DKernelPinMapping* mapping = (DKernelPinMapping*)aMapObject; |
|
2458 if (mapping->IsAttached()) |
|
2459 mapping->UnmapAndUnpin(); |
|
2460 } |
|
2461 |
|
2462 |
|
2463 void M::DestroyKernelMapObject(TKernelMapObject*& aMapObject) |
|
2464 { |
|
2465 DKernelPinMapping* mapping = (DKernelPinMapping*)__e32_atomic_swp_ord_ptr(&aMapObject, 0); |
|
2466 if (mapping) |
|
2467 { |
|
2468 if (mapping->IsAttached()) |
|
2469 mapping->UnmapAndUnpin(); |
|
2470 mapping->AsyncClose(); |
|
2471 } |
|
2472 } |
2371 |
2473 |
2372 |
2474 |
2373 // |
2475 // |
2374 // Cache sync operations |
2476 // Cache sync operations |
2375 // |
2477 // |