kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp
changeset 36 538db54a451d
parent 31 56f325a607ea
child 62 4a8fed1c0ef6
child 90 947f0dc9f7a8
equal deleted inserted replaced
34:f497542af8e4 36:538db54a451d
   437 */
   437 */
   438 TPde Mmu::BlankSectionPde(TMemoryAttributes aAttributes, TUint aPteType)
   438 TPde Mmu::BlankSectionPde(TMemoryAttributes aAttributes, TUint aPteType)
   439 	{
   439 	{
   440 	// reuse existing functions rather than duplicating the logic
   440 	// reuse existing functions rather than duplicating the logic
   441 	TPde pde = BlankPde(aAttributes);
   441 	TPde pde = BlankPde(aAttributes);
   442 	TPde pte = BlankPte(aAttributes, aPteType);
   442 	TPte pte = BlankPte(aAttributes, aPteType);
   443 	return PageToSectionEntry(pte, pde);
   443 	return PageToSectionEntry(pte, pde);
   444 	}
   444 	}
   445 
   445 
   446 
   446 
   447 /**
   447 /**
   880 		}
   880 		}
   881 
   881 
   882 	// Now we have the os asid check access to kernel memory.
   882 	// Now we have the os asid check access to kernel memory.
   883 	if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid)
   883 	if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid)
   884 		{
   884 		{
       
   885 		NKern::ThreadEnterCS();
       
   886 		MmuLock::Unlock();
   885 		if (!iAliasLinAddr)
   887 		if (!iAliasLinAddr)
   886 			{// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set.
   888 			{// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set.
   887 			aProcess->AsyncCloseOsAsid();
   889 			aProcess->AsyncCloseOsAsid();	// Asynchronous close as this method should be quick.
   888 			}
   890 			}
   889 		MmuLock::Unlock();
   891 		NKern::ThreadLeaveCS();
   890 		return KErrBadDescriptor; // prevent access to supervisor only memory
   892 		return KErrBadDescriptor; // prevent access to supervisor only memory
   891 		}
   893 		}
   892 
   894 
   893 	// Now we know all accesses to global memory are safe so check if aAddr is global.
   895 	// Now we know all accesses to global memory are safe so check if aAddr is global.
   894 	if(aAddr >= KGlobalMemoryBase)
   896 	if(aAddr >= KGlobalMemoryBase)
   895 		{
   897 		{
   896 		// address is in global section, don't bother aliasing it...
   898 		// address is in global section, don't bother aliasing it...
   897 		if (!iAliasLinAddr)
   899 		if (!iAliasLinAddr)
   898 			{// Close the new reference as not required.
   900 			{// Close the new reference as not required.
   899 			aProcess->AsyncCloseOsAsid();
   901 			NKern::ThreadEnterCS();
       
   902 			MmuLock::Unlock();
       
   903 			aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
       
   904 			NKern::ThreadLeaveCS();
   900 			}
   905 			}
   901 		else
   906 		else
   902 			{// Remove the existing alias as it is not required.
   907 			{// Remove the existing alias as it is not required.
   903 			DoRemoveAlias(iAliasLinAddr);
   908 			DoRemoveAlias(iAliasLinAddr);	// Releases mmulock.
   904 			}
   909 			}
   905 		MmuLock::Unlock();
       
   906 		aAliasAddr = aAddr;
   910 		aAliasAddr = aAddr;
   907 		TInt maxSize = KChunkSize-(aAddr&KChunkMask);
   911 		TInt maxSize = KChunkSize-(aAddr&KChunkMask);
   908 		aAliasSize = aSize<maxSize ? aSize : maxSize;
   912 		aAliasSize = aSize<maxSize ? aSize : maxSize;
   909 		TRACE2(("DMemModelThread::Alias() abandoned as memory is globally mapped"));
   913 		TRACE2(("DMemModelThread::Alias() abandoned as memory is globally mapped"));
   910 		return KErrNone;
   914 		return KErrNone;
   980 	TLinAddr addr = iAliasLinAddr;
   984 	TLinAddr addr = iAliasLinAddr;
   981 	if(addr)
   985 	if(addr)
   982 		{
   986 		{
   983 		MmuLock::Lock();
   987 		MmuLock::Lock();
   984 
   988 
   985 		DoRemoveAlias(addr);
   989 		DoRemoveAlias(addr);	// Unlocks mmulock.
   986 
       
   987 		MmuLock::Unlock();
       
   988 		}
   990 		}
   989 	}
   991 	}
   990 
   992 
   991 
   993 
   992 /**
   994 /**
   993 Remove the alias mapping.
   995 Remove the alias mapping.
   994 
   996 
   995 @pre Mmulock held
   997 @pre Mmulock held
       
   998 @post MmuLock released.
   996 */
   999 */
   997 void DMemModelThread::DoRemoveAlias(TLinAddr aAddr)
  1000 void DMemModelThread::DoRemoveAlias(TLinAddr aAddr)
   998 	{
  1001 	{
   999 	LockIPCAlias();
  1002 	LockIPCAlias();
  1000 	iAliasLinAddr = 0;
  1003 	iAliasLinAddr = 0;
  1009 #ifdef __SMP__
  1012 #ifdef __SMP__
  1010 	__NK_ASSERT_DEBUG(iCpuRestoreCookie>=0);
  1013 	__NK_ASSERT_DEBUG(iCpuRestoreCookie>=0);
  1011 	NKern::EndFreezeCpu(iCpuRestoreCookie);
  1014 	NKern::EndFreezeCpu(iCpuRestoreCookie);
  1012 	iCpuRestoreCookie = -1;
  1015 	iCpuRestoreCookie = -1;
  1013 #endif
  1016 #endif
  1014 	// Must close the os asid while the mmu lock is held to prevent it being 
  1017 
  1015 	// leaked, however this requires that it is closed asynchronously as can't
  1018 	// Must close the os asid while in critical section to prevent it being 
  1016 	// delete os asid with mmu lock held.
  1019 	// leaked.  However, we can't hold the mmu lock so we have to enter an 
  1017 	iAliasProcess->AsyncCloseOsAsid();
  1020 	// explict crtical section. It is ok to release the mmu lock as the 
       
  1021 	// iAliasLinAddr and iAliasProcess members are only ever updated by the 
       
  1022 	// current thread.
       
  1023 	NKern::ThreadEnterCS();
       
  1024 	MmuLock::Unlock();
       
  1025 	iAliasProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
       
  1026 	NKern::ThreadLeaveCS();
  1018 	}
  1027 	}
  1019 
  1028 
  1020 
  1029 
  1021 TInt M::DemandPagingFault(TAny* aExceptionInfo)
  1030 TInt M::DemandPagingFault(TAny* aExceptionInfo)
  1022 	{
  1031 	{