kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp
branchRCL_3
changeset 22 2f92ad2dc5db
parent 20 597aaf25e343
child 24 41f0cfe18c80
equal deleted inserted replaced
21:e7d2d738d3c2 22:2f92ad2dc5db
   310 						EMemModelAttrVA|EMemModelAttrProcessProt|EMemModelAttrSameVA|EMemModelAttrSvKernProt|
   310 						EMemModelAttrVA|EMemModelAttrProcessProt|EMemModelAttrSameVA|EMemModelAttrSvKernProt|
   311 						EMemModelAttrIPCKernProt|EMemModelAttrRamCodeProt;
   311 						EMemModelAttrIPCKernProt|EMemModelAttrRamCodeProt;
   312 	}
   312 	}
   313 
   313 
   314 
   314 
   315 #if 0
   315 #ifdef FMM_VERIFY_RAM
       
   316 // Attempt to write to each unused RAM page and verify the contents.
   316 void Mmu::VerifyRam()
   317 void Mmu::VerifyRam()
   317 	{
   318 	{
   318 	Kern::Printf("Mmu::VerifyRam() pass 1");
   319 	Kern::Printf("Mmu::VerifyRam() pass 1");
   319 	RamAllocLock::Lock();
   320 	RamAllocLock::Lock();
   320 
   321 
   472 					TInt r = iRamPageAllocator->MarkPageAllocated(pa, EPageFixed);
   473 					TInt r = iRamPageAllocator->MarkPageAllocated(pa, EPageFixed);
   473 					// allow KErrAlreadyExists since it's possible that a page is doubly mapped
   474 					// allow KErrAlreadyExists since it's possible that a page is doubly mapped
   474 					__ASSERT_ALWAYS(r==KErrNone || r==KErrAlreadyExists, Panic(EBadMappedPageAfterBoot));
   475 					__ASSERT_ALWAYS(r==KErrNone || r==KErrAlreadyExists, Panic(EBadMappedPageAfterBoot));
   475 					if(pi->Type()==SPageInfo::EUnused)
   476 					if(pi->Type()==SPageInfo::EUnused)
   476 						pi->SetFixed();
   477 						pi->SetFixed();
       
   478 #ifdef BTRACE_KERNEL_MEMORY
       
   479 					if(r == KErrNone)
       
   480 						++Epoc::KernelMiscPages;
       
   481 #endif
   477 					}
   482 					}
   478 				}
   483 				}
   479 			}
   484 			}
   480 		__KTRACE_OPT(KBOOT,Kern::Printf("Addr: %08x #PTEs=%d",(i<<KChunkShift),np));
   485 		__KTRACE_OPT(KBOOT,Kern::Printf("Addr: %08x #PTEs=%d",(i<<KChunkShift),np));
   481 		if(pt)
   486 		if(pt)
   498 
   503 
   499 	iPhysMemSyncTemp.Alloc(1);
   504 	iPhysMemSyncTemp.Alloc(1);
   500 	r = K::MutexCreate(iPhysMemSyncMutex, KLitPhysMemSync, NULL, EFalse, KMutexOrdSyncPhysMem);
   505 	r = K::MutexCreate(iPhysMemSyncMutex, KLitPhysMemSync, NULL, EFalse, KMutexOrdSyncPhysMem);
   501 	if(r!=KErrNone)
   506 	if(r!=KErrNone)
   502 		Panic(EPhysMemSyncMutexCreateFailed);
   507 		Panic(EPhysMemSyncMutexCreateFailed);
   503 //	VerifyRam();
   508 
       
   509 #ifdef FMM_VERIFY_RAM
       
   510 	VerifyRam();
       
   511 #endif
   504 	}
   512 	}
   505 
   513 
   506 
   514 
   507 void Mmu::Init2FinalCommon()
   515 void Mmu::Init2FinalCommon()
   508 	{
   516 	{
   509 	__KTRACE_OPT2(KBOOT,KMMU,Kern::Printf("Mmu::Init2FinalCommon"));
   517 	__KTRACE_OPT2(KBOOT,KMMU,Kern::Printf("Mmu::Init2FinalCommon"));
   510 	// hack, reduce free memory to <2GB...
   518 	// Reduce free memory to <2GB...
   511 	while(FreeRamInPages()>=0x80000000/KPageSize)
   519 	while(FreeRamInPages()>=0x80000000/KPageSize)
   512 		{
   520 		{
   513 		TPhysAddr dummyPage;
   521 		TPhysAddr dummyPage;
   514 		TInt r = iRamPageAllocator->AllocRamPages(&dummyPage,1, EPageFixed);
   522 		TInt r = iRamPageAllocator->AllocRamPages(&dummyPage,1, EPageFixed);
   515 		__NK_ASSERT_ALWAYS(r==KErrNone);
   523 		__NK_ASSERT_ALWAYS(r==KErrNone);
   516 		}
   524 		}
   517 	// hack, reduce total RAM to <2GB...
   525 	// Reduce total RAM to <2GB...
   518 	if(TheSuperPage().iTotalRamSize<0)
   526 	if(TheSuperPage().iTotalRamSize<0)
   519 		TheSuperPage().iTotalRamSize = 0x80000000-KPageSize;
   527 		TheSuperPage().iTotalRamSize = 0x80000000-KPageSize;
   520 
   528 
   521 	// Save current free RAM size - there can never be more free RAM than this
   529 	// Save current free RAM size - there can never be more free RAM than this
   522 	TUint maxFreePages = FreeRamInPages();
   530 	TUint maxFreePages = FreeRamInPages();
   538 	if (!iDefrag)
   546 	if (!iDefrag)
   539 		Panic(EDefragAllocFailed);
   547 		Panic(EDefragAllocFailed);
   540 	iDefrag->Init3(TheMmu.iRamPageAllocator);
   548 	iDefrag->Init3(TheMmu.iRamPageAllocator);
   541 	}
   549 	}
   542 
   550 
       
   551 
       
   552 void Mmu::BTracePrime(TUint aCategory)
       
   553 	{
       
   554 	(void)aCategory;
       
   555 
       
   556 #ifdef BTRACE_RAM_ALLOCATOR
       
   557 	// Must check for -1 as that is the default value of aCategory for
       
   558 	// BTrace::Prime() which is intended to prime all categories that are 
       
   559 	// currently enabled via a single invocation of BTrace::Prime().
       
   560 	if(aCategory==BTrace::ERamAllocator || (TInt)aCategory == -1)
       
   561 		{
       
   562 		NKern::ThreadEnterCS();
       
   563 		RamAllocLock::Lock();
       
   564 		iRamPageAllocator->DoBTracePrime();
       
   565 		RamAllocLock::Unlock();
       
   566 		NKern::ThreadLeaveCS();
       
   567 		}
       
   568 #endif
       
   569 	}
       
   570 
       
   571 
   543 //
   572 //
   544 // Utils
   573 // Utils
   545 //
   574 //
   546 
   575 
   547 void Mmu::Panic(TPanic aPanic)
   576 void Mmu::Panic(TPanic aPanic)
   617 	else
   646 	else
   618 		{
   647 		{
   619 		PagesAllocated(aPageList, aNumPages, (Mmu::TRamAllocFlags)EMemAttStronglyOrdered);
   648 		PagesAllocated(aPageList, aNumPages, (Mmu::TRamAllocFlags)EMemAttStronglyOrdered);
   620 
   649 
   621 		// update page infos...
   650 		// update page infos...
   622 		TUint flash = 0;
   651 		SetAllocPhysRam(aPageList, aNumPages);
   623 		TPhysAddr* pageEnd = aPageList + aNumPages;
       
   624 		MmuLock::Lock();
       
   625 		TPhysAddr* page = aPageList;
       
   626 		while (page < pageEnd)
       
   627 			{
       
   628 			MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo/2);
       
   629 			TPhysAddr pagePhys = *page++;
       
   630 			__NK_ASSERT_DEBUG(pagePhys != KPhysAddrInvalid);
       
   631 			SPageInfo::FromPhysAddr(pagePhys)->SetPhysAlloc();
       
   632 			}
       
   633 		MmuLock::Unlock();
       
   634 		}
   652 		}
   635 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::ZoneAllocPhysicalRam returns %d",r));
   653 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::ZoneAllocPhysicalRam returns %d",r));
   636 	return r;
   654 	return r;
   637 	}
   655 	}
   638 
   656 
   961 	TInt r = AllocRam(aPages, aCount, aFlags, EPageFixed);
   979 	TInt r = AllocRam(aPages, aCount, aFlags, EPageFixed);
   962 	if (r!=KErrNone)
   980 	if (r!=KErrNone)
   963 		return r;
   981 		return r;
   964 
   982 
   965 	// update page infos...
   983 	// update page infos...
   966 	TPhysAddr* pages = aPages;
   984 	SetAllocPhysRam(aPages, aCount);
   967 	TPhysAddr* pagesEnd = pages+aCount;
       
   968 	MmuLock::Lock();
       
   969 	TUint flash = 0;
       
   970 	while(pages<pagesEnd)
       
   971 		{
       
   972 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo/2);
       
   973 		TPhysAddr pagePhys = *pages++;
       
   974 		__NK_ASSERT_DEBUG(pagePhys!=KPhysAddrInvalid);
       
   975 		SPageInfo* pi = SPageInfo::FromPhysAddr(pagePhys);
       
   976 		pi->SetPhysAlloc();
       
   977 		}
       
   978 	MmuLock::Unlock();
       
   979 
   985 
   980 	return KErrNone;
   986 	return KErrNone;
   981 	}
   987 	}
   982 
   988 
   983 
   989 
  1002 		pi->SetUnused();
  1008 		pi->SetUnused();
  1003 		}
  1009 		}
  1004 	MmuLock::Unlock();
  1010 	MmuLock::Unlock();
  1005 
  1011 
  1006 	iRamPageAllocator->FreeRamPages(aPages,aCount, EPageFixed);
  1012 	iRamPageAllocator->FreeRamPages(aPages,aCount, EPageFixed);
       
  1013 
       
  1014 #ifdef BTRACE_KERNEL_MEMORY
       
  1015 	if (BTrace::CheckFilter(BTrace::EKernelMemory))
       
  1016 		{// Only loop round each page if EKernelMemory tracing is enabled
       
  1017 		pages = aPages;
       
  1018 		pagesEnd = aPages + aCount;
       
  1019 		while (pages < pagesEnd)
       
  1020 			{
       
  1021 			BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysFree, KPageSize, *pages++);
       
  1022 			Epoc::DriverAllocdPhysRam -= KPageSize;
       
  1023 			}
       
  1024 		}
       
  1025 #endif
  1007 	}
  1026 	}
  1008 
  1027 
  1009 
  1028 
  1010 TInt Mmu::AllocPhysicalRam(TPhysAddr& aPhysAddr, TUint aCount, TUint aAlign, TRamAllocFlags aFlags)
  1029 TInt Mmu::AllocPhysicalRam(TPhysAddr& aPhysAddr, TUint aCount, TUint aAlign, TRamAllocFlags aFlags)
  1011 	{
  1030 	{
  1012 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocPhysicalRam(?,0x%x,d,%x)",aCount,aAlign,aFlags));
  1031 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocPhysicalRam(?,0x%x,d,%x)",aCount,aAlign,aFlags));
  1013 	TInt r = AllocContiguousRam(aPhysAddr,aCount,aAlign,aFlags);
  1032 	TInt r = AllocContiguousRam(aPhysAddr,aCount,aAlign,aFlags);
  1014 	if (r!=KErrNone)
  1033 	if (r!=KErrNone)
  1015 		return r;
  1034 		return r;
       
  1035 
       
  1036 	// update page infos...
       
  1037 	SetAllocPhysRam(aPhysAddr, aCount);
       
  1038 
       
  1039 	return KErrNone;
       
  1040 	}
       
  1041 
       
  1042 
       
  1043 void Mmu::FreePhysicalRam(TPhysAddr aPhysAddr, TUint aCount)
       
  1044 	{
       
  1045 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::FreePhysicalRam(0x%08x,0x%x)",aPhysAddr,aCount));
  1016 
  1046 
  1017 	// update page infos...
  1047 	// update page infos...
  1018 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
  1048 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
  1019 	SPageInfo* piEnd = pi+aCount;
  1049 	SPageInfo* piEnd = pi+aCount;
  1020 	TUint flash = 0;
  1050 	TUint flash = 0;
  1021 	MmuLock::Lock();
  1051 	MmuLock::Lock();
  1022 	while(pi<piEnd)
  1052 	while(pi<piEnd)
  1023 		{
  1053 		{
  1024 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo);
  1054 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo);
  1025 		pi->SetPhysAlloc();
  1055 		__ASSERT_ALWAYS(pi->Type()==SPageInfo::EPhysAlloc, Panic(EBadFreePhysicalRam));
       
  1056 		__ASSERT_ALWAYS(!pi->UseCount(), Panic(EBadFreePhysicalRam));
       
  1057 		pi->SetUnused();
  1026 		++pi;
  1058 		++pi;
  1027 		}
  1059 		}
  1028 	MmuLock::Unlock();
  1060 	MmuLock::Unlock();
  1029 
  1061 
       
  1062 	TUint bytes = aCount << KPageShift;
       
  1063 	iRamPageAllocator->FreePhysicalRam(aPhysAddr, bytes);
       
  1064 
       
  1065 #ifdef BTRACE_KERNEL_MEMORY
       
  1066 	BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysFree, bytes, aPhysAddr);
       
  1067 	Epoc::DriverAllocdPhysRam -= bytes;
       
  1068 #endif
       
  1069 	}
       
  1070 
       
  1071 
       
  1072 TInt Mmu::ClaimPhysicalRam(TPhysAddr aPhysAddr, TUint aCount, TRamAllocFlags aFlags)
       
  1073 	{
       
  1074 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::ClaimPhysicalRam(0x%08x,0x%x,0x%08x)",aPhysAddr,aCount,aFlags));
       
  1075 	aPhysAddr &= ~KPageMask;
       
  1076 	TInt r = iRamPageAllocator->ClaimPhysicalRam(aPhysAddr, aCount << KPageShift);
       
  1077 	if(r != KErrNone)
       
  1078 		return r;
       
  1079 
       
  1080 	AllocatedPhysicalRam(aPhysAddr, aCount, aFlags);
  1030 	return KErrNone;
  1081 	return KErrNone;
  1031 	}
  1082 	}
  1032 
  1083 
  1033 
  1084 
  1034 void Mmu::FreePhysicalRam(TPhysAddr aPhysAddr, TUint aCount)
  1085 void Mmu::AllocatedPhysicalRam(TPhysAddr aPhysAddr, TUint aCount, TRamAllocFlags aFlags)
  1035 	{
  1086 	{
  1036 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::FreePhysicalRam(0x%08x,0x%x)",aPhysAddr,aCount));
  1087 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocatedPhysicalRam(0x%08x,0x%x,d,%x)",aPhysAddr,aCount,aFlags));
       
  1088 
       
  1089 	PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
  1037 
  1090 
  1038 	// update page infos...
  1091 	// update page infos...
       
  1092 	SetAllocPhysRam(aPhysAddr, aCount);
       
  1093 	}
       
  1094 
       
  1095 
       
  1096 void Mmu::SetAllocPhysRam(TPhysAddr aPhysAddr, TUint aCount)
       
  1097 	{
  1039 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
  1098 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
  1040 	SPageInfo* piEnd = pi+aCount;
  1099 	SPageInfo* piEnd = pi+aCount;
  1041 	TUint flash = 0;
  1100 	TUint flash = 0;
  1042 	MmuLock::Lock();
  1101 	MmuLock::Lock();
  1043 	while(pi<piEnd)
  1102 	while(pi<piEnd)
  1044 		{
  1103 		{
  1045 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo);
  1104 		MmuLock::Flash(flash, KMaxPageInfoUpdatesInOneGo);
  1046 		__ASSERT_ALWAYS(pi->Type()==SPageInfo::EPhysAlloc, Panic(EBadFreePhysicalRam));
  1105 		pi->SetPhysAlloc();
  1047 		__ASSERT_ALWAYS(!pi->UseCount(), Panic(EBadFreePhysicalRam));
       
  1048 		pi->SetUnused();
       
  1049 		++pi;
  1106 		++pi;
  1050 		}
  1107 		}
  1051 	MmuLock::Unlock();
  1108 	MmuLock::Unlock();
  1052 
  1109 
  1053 	iRamPageAllocator->FreePhysicalRam(aPhysAddr, aCount << KPageShift);
  1110 #ifdef BTRACE_KERNEL_MEMORY
  1054 	}
  1111 	TUint bytes = aCount << KPageShift;
  1055 
  1112 	BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysAlloc, bytes, aPhysAddr);
  1056 
  1113 	Epoc::DriverAllocdPhysRam += bytes;
  1057 TInt Mmu::ClaimPhysicalRam(TPhysAddr aPhysAddr, TUint aCount, TRamAllocFlags aFlags)
  1114 #endif
  1058 	{
  1115 	}
  1059 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::ClaimPhysicalRam(0x%08x,0x%x,0x%08x)",aPhysAddr,aCount,aFlags));
  1116 
  1060 	aPhysAddr &= ~KPageMask;
  1117 
  1061 	TInt r = iRamPageAllocator->ClaimPhysicalRam(aPhysAddr,(aCount << KPageShift));
  1118 void Mmu::SetAllocPhysRam(TPhysAddr* aPageList, TUint aNumPages)
  1062 	if(r!=KErrNone)
  1119 	{
  1063 		return r;
  1120 	TPhysAddr* page = aPageList;
  1064 
  1121 	TPhysAddr* pageEnd = aPageList + aNumPages;
  1065 	PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
       
  1066 
       
  1067 	// update page infos...
       
  1068 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
       
  1069 	SPageInfo* piEnd = pi+aCount;
       
  1070 	TUint flash = 0;
  1122 	TUint flash = 0;
  1071 	MmuLock::Lock();
  1123 	MmuLock::Lock();
  1072 	while(pi<piEnd)
  1124 	while (page < pageEnd)
  1073 		{
  1125 		{
  1074 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo);
  1126 		MmuLock::Flash(flash, KMaxPageInfoUpdatesInOneGo / 2);
  1075 		pi->SetPhysAlloc();
  1127 		TPhysAddr pagePhys = *page++;
  1076 		++pi;
  1128 		__NK_ASSERT_DEBUG(pagePhys != KPhysAddrInvalid);
       
  1129 		SPageInfo::FromPhysAddr(pagePhys)->SetPhysAlloc();
  1077 		}
  1130 		}
  1078 	MmuLock::Unlock();
  1131 	MmuLock::Unlock();
  1079 
  1132 
  1080 	return KErrNone;
  1133 #ifdef BTRACE_KERNEL_MEMORY
  1081 	}
  1134 	if (BTrace::CheckFilter(BTrace::EKernelMemory))
  1082 
  1135 		{// Only loop round each page if EKernelMemory tracing is enabled
  1083 
  1136 		TPhysAddr* pAddr = aPageList;
  1084 void Mmu::AllocatedPhysicalRam(TPhysAddr aPhysAddr, TUint aCount, TRamAllocFlags aFlags)
  1137 		TPhysAddr* pAddrEnd = aPageList + aNumPages;
  1085 	{
  1138 		while (pAddr < pAddrEnd)
  1086 	__KTRACE_OPT(KMMU,Kern::Printf("Mmu::AllocatedPhysicalRam(0x%08x,0x%x,d,%x)",aPhysAddr,aCount,aFlags));
  1139 			{
  1087 
  1140 			BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysAlloc, KPageSize, *pAddr++);
  1088 	PagesAllocated((TPhysAddr*)(aPhysAddr|1), aCount, aFlags);
  1141 			Epoc::DriverAllocdPhysRam += KPageSize;
  1089 
  1142 			}
  1090 	// update page infos...
  1143 		}
  1091 	SPageInfo* pi = SPageInfo::FromPhysAddr(aPhysAddr);
  1144 #endif
  1092 	SPageInfo* piEnd = pi+aCount;
       
  1093 	TUint flash = 0;
       
  1094 	MmuLock::Lock();
       
  1095 	while(pi<piEnd)
       
  1096 		{
       
  1097 		MmuLock::Flash(flash,KMaxPageInfoUpdatesInOneGo);
       
  1098 		pi->SetPhysAlloc();
       
  1099 		++pi;
       
  1100 		}
       
  1101 	MmuLock::Unlock();
       
  1102 	}
  1145 	}
  1103 
  1146 
  1104 
  1147 
  1105 //
  1148 //
  1106 // Misc
  1149 // Misc
  1185 TLinAddr Mmu::TTempMapping::Map(TPhysAddr aPage, TUint aColour)
  1228 TLinAddr Mmu::TTempMapping::Map(TPhysAddr aPage, TUint aColour)
  1186 	{
  1229 	{
  1187 	__NK_ASSERT_DEBUG(iSize>=1);
  1230 	__NK_ASSERT_DEBUG(iSize>=1);
  1188 	__NK_ASSERT_DEBUG(iCount==0);
  1231 	__NK_ASSERT_DEBUG(iCount==0);
  1189 
  1232 
       
  1233 	return Map(aPage, aColour, iBlankPte);
       
  1234 	}
       
  1235 
       
  1236 
       
  1237 /**
       
  1238 Map a single physical page into this temporary mapping using the given page table entry (PTE) value.
       
  1239 
       
  1240 @param aPage		The physical page to map.
       
  1241 @param aColour 		The required colour for the mapping.
       
  1242 @param aBlankPte	The PTE value to use for mapping the page,
       
  1243 					with the physical address component equal to zero.
       
  1244 
       
  1245 @return 			The linear address at which the page is mapped.
       
  1246 */
       
  1247 TLinAddr Mmu::TTempMapping::Map(TPhysAddr aPage, TUint aColour, TPte aBlankPte)
       
  1248 	{
       
  1249 	__NK_ASSERT_DEBUG(iSize>=1);
       
  1250 	__NK_ASSERT_DEBUG(iCount==0);
       
  1251 	__NK_ASSERT_DEBUG(!(aBlankPte & ~KPageMask));
       
  1252 
       
  1253 	TUint colour = aColour & KPageColourMask;
       
  1254 	TLinAddr addr = iLinAddr + (colour << KPageShift);
       
  1255 	TPte* pPte = iPtePtr + colour;
       
  1256 	iColour = colour;
       
  1257 
       
  1258 	__ASSERT_DEBUG(*pPte == KPteUnallocatedEntry, MM::Panic(MM::ETempMappingAlreadyInUse));
       
  1259 	*pPte = (aPage & ~KPageMask) | aBlankPte;
       
  1260 	CacheMaintenance::SinglePteUpdated((TLinAddr)pPte);
       
  1261 	InvalidateTLBForPage(addr | KKernelOsAsid);
       
  1262 
       
  1263 	iCount = 1;
       
  1264 	return addr;
       
  1265 	}
       
  1266 
       
  1267 
       
  1268 /**
       
  1269 Map a number of physical pages into this temporary mapping.
       
  1270 
       
  1271 Supervisor read/write access and EMemoryAttributeStandard memory attributes apply.
       
  1272 
       
  1273 @param aPages		The array of physical pages to map.
       
  1274 @param aCount		The number of pages to map.
       
  1275 @param aColour 		The required colour for the first page.
       
  1276 					Consecutive pages will be coloured accordingly.
       
  1277 
       
  1278 @return 			The linear address at which the first page is mapped.
       
  1279 */
       
  1280 TLinAddr Mmu::TTempMapping::Map(TPhysAddr* aPages, TUint aCount, TUint aColour)
       
  1281 	{
       
  1282 	__NK_ASSERT_DEBUG(iSize>=aCount);
       
  1283 	__NK_ASSERT_DEBUG(iCount==0);
       
  1284 
  1190 	TUint colour = aColour&KPageColourMask;
  1285 	TUint colour = aColour&KPageColourMask;
  1191 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
  1286 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
  1192 	TPte* pPte = iPtePtr+colour;
  1287 	TPte* pPte = iPtePtr+colour;
  1193 	iColour = colour;
  1288 	iColour = colour;
  1194 
  1289 
  1195 	__ASSERT_DEBUG(*pPte==KPteUnallocatedEntry,MM::Panic(MM::ETempMappingAlreadyInUse));
       
  1196 	*pPte = (aPage&~KPageMask) | iBlankPte;
       
  1197 	CacheMaintenance::SinglePteUpdated((TLinAddr)pPte);
       
  1198 	InvalidateTLBForPage(addr|KKernelOsAsid);
       
  1199 
       
  1200 	iCount = 1;
       
  1201 	return addr;
       
  1202 	}
       
  1203 
       
  1204 /**
       
  1205 Map a single physical page into this temporary mapping using the given page table entry (PTE) value.
       
  1206 
       
  1207 @param aPage		The physical page to map.
       
  1208 @param aColour 		The required colour for the mapping.
       
  1209 @param aBlankPte	The PTE value to use for mapping the page,
       
  1210 					with the physical address component equal to zero.
       
  1211 
       
  1212 @return 			The linear address at which the page is mapped.
       
  1213 */
       
  1214 TLinAddr Mmu::TTempMapping::Map(TPhysAddr aPage, TUint aColour, TPte aBlankPte)
       
  1215 	{
       
  1216 	__NK_ASSERT_DEBUG(iSize>=1);
       
  1217 	__NK_ASSERT_DEBUG(iCount==0);
       
  1218 
       
  1219 	TUint colour = aColour&KPageColourMask;
       
  1220 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
       
  1221 	TPte* pPte = iPtePtr+colour;
       
  1222 	iColour = colour;
       
  1223 
       
  1224 	__ASSERT_DEBUG(*pPte==KPteUnallocatedEntry,MM::Panic(MM::ETempMappingAlreadyInUse));
       
  1225 	*pPte = (aPage&~KPageMask) | aBlankPte;
       
  1226 	CacheMaintenance::SinglePteUpdated((TLinAddr)pPte);
       
  1227 	InvalidateTLBForPage(addr|KKernelOsAsid);
       
  1228 
       
  1229 	iCount = 1;
       
  1230 	return addr;
       
  1231 	}
       
  1232 
       
  1233 
       
  1234 /**
       
  1235 Map a number of physical pages into this temporary mapping.
       
  1236 
       
  1237 Supervisor read/write access and EMemoryAttributeStandard memory attributes apply.
       
  1238 
       
  1239 @param aPages		The array of physical pages to map.
       
  1240 @param aCount		The number of pages to map.
       
  1241 @param aColour 		The required colour for the first page.
       
  1242 					Consecutive pages will be coloured accordingly.
       
  1243 
       
  1244 @return 			The linear address at which the first page is mapped.
       
  1245 */
       
  1246 TLinAddr Mmu::TTempMapping::Map(TPhysAddr* aPages, TUint aCount, TUint aColour)
       
  1247 	{
       
  1248 	__NK_ASSERT_DEBUG(iSize>=aCount);
       
  1249 	__NK_ASSERT_DEBUG(iCount==0);
       
  1250 
       
  1251 	TUint colour = aColour&KPageColourMask;
       
  1252 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
       
  1253 	TPte* pPte = iPtePtr+colour;
       
  1254 	iColour = colour;
       
  1255 
       
  1256 	for(TUint i=0; i<aCount; ++i)
  1290 	for(TUint i=0; i<aCount; ++i)
  1257 		{
  1291 		{
  1258 		__ASSERT_DEBUG(pPte[i]==KPteUnallocatedEntry,MM::Panic(MM::ETempMappingAlreadyInUse));
  1292 		__ASSERT_DEBUG(pPte[i]==KPteUnallocatedEntry,MM::Panic(MM::ETempMappingAlreadyInUse));
  1259 		pPte[i] = (aPages[i]&~KPageMask) | iBlankPte;
  1293 		pPte[i] = (aPages[i]&~KPageMask) | iBlankPte;
  1260 		CacheMaintenance::SinglePteUpdated((TLinAddr)&pPte[i]);
  1294 		CacheMaintenance::SinglePteUpdated((TLinAddr)&pPte[i]);
  1288 	__NK_ASSERT_DEBUG(iSize>=1);
  1322 	__NK_ASSERT_DEBUG(iSize>=1);
  1289 
  1323 
  1290 	TUint colour = iColour;
  1324 	TUint colour = iColour;
  1291 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
  1325 	TLinAddr addr = iLinAddr+(colour<<KPageShift);
  1292 	TPte* pPte = iPtePtr+colour;
  1326 	TPte* pPte = iPtePtr+colour;
  1293 	TUint count = iCount;
  1327 
  1294 
  1328 	while(iCount)
  1295 	while(count)
       
  1296 		{
  1329 		{
  1297 		*pPte = KPteUnallocatedEntry;
  1330 		*pPte = KPteUnallocatedEntry;
  1298 		CacheMaintenance::SinglePteUpdated((TLinAddr)pPte);
  1331 		CacheMaintenance::SinglePteUpdated((TLinAddr)pPte);
  1299 		InvalidateTLBForPage(addr|KKernelOsAsid);
  1332 		InvalidateTLBForPage(addr|KKernelOsAsid);
  1300 		addr += KPageSize;
  1333 		addr += KPageSize;
  1301 		++pPte;
  1334 		++pPte;
  1302 		--count;
  1335 		--iCount;
  1303 		}
  1336 		}
  1304 
       
  1305 	iCount = 0;
       
  1306 	}
  1337 	}
  1307 
  1338 
  1308 #ifdef __SMP__
  1339 #ifdef __SMP__
  1309 /**
  1340 /**
  1310 Dummy IPI to be invoked when a thread's alias pde members are updated remotely
  1341 Dummy IPI to be invoked when a thread's alias pde members are updated remotely