--- a/.hgtags Mon Mar 08 11:57:08 2010 +0000
+++ b/.hgtags Sun Mar 14 13:15:32 2010 +0000
@@ -1,2 +1,4 @@
a41df078684ad3b64d71f9407a748f84d50d35b1 PDK_3.0.b
f828418ede2a3e3e1cecc4b3424860ae81a94969 PDK_3.0.c
+2e0eeacfdf124e1e2e0ce6542de80bdc58a07096 PDK_3.0.d
+6d8ad5bee44b0ca68eb8fcfd99b3bc471c613594 PDK_3.0.e
--- a/bsptemplate/asspandvariant/template_variant/bld.inf Mon Mar 08 11:57:08 2010 +0000
+++ b/bsptemplate/asspandvariant/template_variant/bld.inf Sun Mar 14 13:15:32 2010 +0000
@@ -108,12 +108,39 @@
//
PRJ_EXTENSIONS
-start extension base/bootstrap
+
+#if 0 // Removing changes associated with introduction of bootstrap.flm - see Bug 2149
+#ifdef SBSV2 // If using SBSv2 with bootstrap FLM, MEMMODEL MUST begin with a capital letter
+
+start extension base.bootstrap bootstrap
#ifdef SYMBIAN_OLD_EXPORT_LOCATION
-option INC_PATH /epoc32/include
+option INC_PATH $(EPOCROOT)epoc32/include
#else
-option INC_PATH /epoc32/include/platform
+option INC_PATH $(EPOCROOT)epoc32/include/platform
+#endif
+
+option NAME _template_bootrom
+option CPU arm
+option MEMMODEL Multiple
+option SOURCES ./bootstrap/template.s
+option EXTRA_SRC_PATH ./bootstrap
+option INCLUDES ./config.inc
+option E32PATH ../../../kernel/eka/../.
+
+end
+
+#else // !SBSV2
+#endif // more workaround - close the #ifdef SBSV2 here, to regain the other bit
+#endif // first part of workaround - close the #ifdef 0
+
+
+start extension base/bootstrap bootstrap
+
+#ifdef SYMBIAN_OLD_EXPORT_LOCATION
+option INC_PATH $(EPOCROOT)epoc32/include
+#else
+option INC_PATH $(EPOCROOT)epoc32/include/platform
#endif
option NAME _template_bootrom
@@ -126,3 +153,5 @@
end
+#if 0 // second part of workaround - avoid dangling #endif
+#endif // !SBSV2
--- a/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -182,6 +182,10 @@
{
DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr;
Interrupt::Disable(KIntIdKeyboard);
+
+ // Add the timing of key interrupts as entropy data for the RNG
+ Interrupt::AddTimingEntropy();
+
k.iEventDfc.Add();
}
--- a/bsptemplate/asspandvariant/template_variant/specific/xyin.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/bsptemplate/asspandvariant/template_variant/specific/xyin.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -599,6 +599,9 @@
Interrupt::Disable(KIntIdDigitiser); // do NOT disable the capability to generate interrupts at the source
+ // Add the timing of pen interrupts as entropy data for the RNG
+ Interrupt::AddTimingEntropy();
+
if (KPenDownDelayTime>0) // need to check this config param as it might be zero!
iTimerInt.OneShot(KPenDownDelayTime); // start a debounce timer which will queue a DFC to process the interrupt
else
--- a/kernel/eka/base_e32.mrp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/base_e32.mrp Sun Mar 14 13:15:32 2010 +0000
@@ -32,15 +32,15 @@
binary \sf\os\kernelhwsrv\kernel\eka all
exports \sf\os\kernelhwsrv\kernel\eka
--export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec.zip \epoc32\include\exec_enum.h
--export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec.zip \epoc32\include\exec_user.h
--export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec.zip \epoc32\include\kernel\exec_kernel.h
+-export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec_hr.zip \epoc32\include\platform\exec_enum.h
+-export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec_hr.zip \epoc32\include\platform\exec_user.h
+-export_file \sf\os\kernelhwsrv\kernel\eka\include\dummy_genexec_hr.zip \epoc32\include\platform\kernel\exec_kernel.h
notes_source \component_defs\release.src
-binary \epoc32\include\exec_enum.h
-binary \epoc32\include\exec_user.h
-binary \epoc32\include\kernel\exec_kernel.h
+binary \epoc32\include\platform\exec_enum.h
+binary \epoc32\include\platform\exec_user.h
+binary \epoc32\include\platform\kernel\exec_kernel.h
ipr D
ipr D \sf\os\kernelhwsrv\kernel\eka\include\memmodel\epoc\multiple\arm
--- a/kernel/eka/bmarm/econs.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bmarm/econs.def Sun Mar 14 13:15:32 2010 +0000
@@ -31,4 +31,5 @@
Type__C11TConsoleKey @ 30 NONAME ; TConsoleKey::Type(void) const
Version__8RConsole @ 31 NONAME ; RConsole::Version(void)
ClearScreen__8RConsole @ 32 NONAME ; RConsole::ClearScreen(void)
+ PointerNumber__C11TConsoleKey @ 33 NONAME ; TConsoleKey::PointerNumber(void) const
--- a/kernel/eka/bmarm/ekernsmp.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bmarm/ekernsmp.def Sun Mar 14 13:15:32 2010 +0000
@@ -1041,4 +1041,9 @@
DestroyKernelMapObject__4KernRP16TKernelMapObject @ 1040 NONAME R3UNUSED ; Kern::DestroyKernelMapObject(TKernelMapObject *&)
MapAndPinMemory__4KernP16TKernelMapObjectP7DThreadUlUiUiRUlPUl @ 1041 NONAME ; Kern::MapAndPinMemory(TKernelMapObject *, DThread *, unsigned long, unsigned int, unsigned int, unsigned long &, unsigned long *)
UnmapAndUnpinMemory__4KernP16TKernelMapObject @ 1042 NONAME R3UNUSED ; Kern::UnmapAndUnpinMemory(TKernelMapObject *)
+ AddTimingEntropy__9Interrupt @ 1043 NONAME R3UNUSED ; Interrupt::AddTimingEntropy(void)
+ RandomSalt__4KernUlUi @ 1044 NONAME R3UNUSED ; Kern::RandomSalt(unsigned long, unsigned int)
+ RandomSalt__4KernUxUi @ 1045 NONAME ; Kern::RandomSalt(unsigned long long, unsigned int)
+ RandomSalt__4KernPCUcUiUi @ 1046 NONAME R3UNUSED ; Kern::RandomSalt(unsigned char const *, unsigned int, unsigned int)
+ SecureRandom__4KernR5TDes8 @ 1047 NONAME R3UNUSED ; Kern::SecureRandom(TDes8 &)
--- a/kernel/eka/bmarm/ekernu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bmarm/ekernu.def Sun Mar 14 13:15:32 2010 +0000
@@ -1037,4 +1037,9 @@
DestroyKernelMapObject__4KernRP16TKernelMapObject @ 1036 NONAME R3UNUSED ; Kern::DestroyKernelMapObject(TKernelMapObject *&)
MapAndPinMemory__4KernP16TKernelMapObjectP7DThreadUlUiUiRUlPUl @ 1037 NONAME ; Kern::MapAndPinMemory(TKernelMapObject *, DThread *, unsigned long, unsigned int, unsigned int, unsigned long &, unsigned long *)
UnmapAndUnpinMemory__4KernP16TKernelMapObject @ 1038 NONAME R3UNUSED ; Kern::UnmapAndUnpinMemory(TKernelMapObject *)
+ AddTimingEntropy__9Interrupt @ 1039 NONAME R3UNUSED ; Interrupt::AddTimingEntropy(void)
+ RandomSalt__4KernUlUi @ 1040 NONAME R3UNUSED ; Kern::RandomSalt(unsigned long, unsigned int)
+ RandomSalt__4KernUxUi @ 1041 NONAME ; Kern::RandomSalt(unsigned long long, unsigned int)
+ RandomSalt__4KernPCUcUiUi @ 1042 NONAME R3UNUSED ; Kern::RandomSalt(unsigned char const *, unsigned int, unsigned int)
+ SecureRandom__4KernR5TDes8 @ 1043 NONAME R3UNUSED ; Kern::SecureRandom(TDes8 &)
--- a/kernel/eka/bmarm/euseru.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bmarm/euseru.def Sun Mar 14 13:15:32 2010 +0000
@@ -2231,4 +2231,8 @@
LoadLocale__15TExtendedLocaleRC7TDesC16N21 @ 2230 NONAME ; TExtendedLocale::LoadLocale(TDesC16 const &, TDesC16 const &, TDesC16 const &)
RegionCode__4User @ 2231 NONAME R3UNUSED ; User::RegionCode(void)
SetReadOnly__16TChunkCreateInfo @ 2232 NONAME R3UNUSED ; TChunkCreateInfo::SetReadOnly(void)
+ RandomL__4MathR5TDes8 @ 2233 NONAME R3UNUSED ; Math::RandomL(TDes8 &)
+ RandomL__4Math @ 2234 NONAME R3UNUSED ; Math::RandomL(void)
+ Random__4MathR5TDes8 @ 2235 NONAME R3UNUSED ; Math::Random(TDes8 &)
+
--- a/kernel/eka/bwins/econs.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bwins/econs.def Sun Mar 14 13:15:32 2010 +0000
@@ -31,4 +31,5 @@
?Type@TConsoleKey@@QBEHXZ @ 30 NONAME ; public: int __thiscall TConsoleKey::Type(void)const
?Version@RConsole@@QAE?AVTVersion@@XZ @ 31 NONAME ; public: class TVersion __thiscall RConsole::Version(void)
?Write@RConsole@@QAEHABVTDesC16@@@Z @ 32 NONAME ; public: int __thiscall RConsole::Write(class TDesC16 const &)
+ ?PointerNumber@TConsoleKey@@QBEEXZ @ 33 NONAME ; public: unsigned char __thiscall TConsoleKey::PointerNumber(void)const
--- a/kernel/eka/bwins/ekernu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bwins/ekernu.def Sun Mar 14 13:15:32 2010 +0000
@@ -925,4 +925,8 @@
?MapAndPinMemory@Kern@@SAHPAVTKernelMapObject@@PAVDThread@@KIIAAKPAK@Z @ 924 NONAME ; int Kern::MapAndPinMemory(class TKernelMapObject *, class DThread *, unsigned long, unsigned int, unsigned int, unsigned long &, unsigned long *)
?CreateKernelMapObject@Kern@@SAHAAPAVTKernelMapObject@@I@Z @ 925 NONAME ; int Kern::CreateKernelMapObject(class TKernelMapObject * &, unsigned int)
?DestroyKernelMapObject@Kern@@SAXAAPAVTKernelMapObject@@@Z @ 926 NONAME ; void Kern::DestroyKernelMapObject(class TKernelMapObject * &)
+ ?RandomSalt@Kern@@SAXKI@Z @ 927 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned long,unsigned int)
+ ?RandomSalt@Kern@@SAX_KI@Z @ 928 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned __int64,unsigned int)
+ ?RandomSalt@Kern@@SAXPBEII@Z @ 929 NONAME ; void Kern::RandomSalt(unsigned char const *, unsigned int, unsigned int)
+ ?SecureRandom@Kern@@SAHAAVTDes8@@@Z @ 930 NONAME ; int Kern::SecureRandom(class TDes8 &)
--- a/kernel/eka/bwins/euseru.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bwins/euseru.def Sun Mar 14 13:15:32 2010 +0000
@@ -2179,4 +2179,8 @@
?LoadLocaleAspect@TExtendedLocale@@QAEHABVTDesC16@@@Z @ 2178 NONAME ; int TExtendedLocale::LoadLocaleAspect(class TDesC16 const &)
?RegionCode@User@@SA?AW4TRegionCode@@XZ @ 2179 NONAME ; enum TRegionCode User::RegionCode(void)
?SetReadOnly@TChunkCreateInfo@@QAEXXZ @ 2180 NONAME ; public: void __thiscall TChunkCreateInfo::SetReadOnly(void)
+ ?RandomL@Math@@SAXAAVTDes8@@@Z @ 2181 NONAME ; void Math::RandomL(class TDes8 &)
+ ?Random@Math@@SAXAAVTDes8@@@Z @ 2182 NONAME ; void Math::Random(class TDes8 &)
+ ?RandomL@Math@@SAKXZ @ 2183 NONAME ; unsigned long Math::RandomL(void)
+
--- a/kernel/eka/bx86/econs.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86/econs.def Sun Mar 14 13:15:32 2010 +0000
@@ -31,4 +31,5 @@
?Type@TConsoleKey@@QBEHXZ @ 30 NONAME ; public: int __thiscall TConsoleKey::Type(void)const
?Version@RConsole@@QAE?AVTVersion@@XZ @ 31 NONAME ; public: class TVersion __thiscall RConsole::Version(void)
?Write@RConsole@@QAEHABVTDesC16@@@Z @ 32 NONAME ; public: int __thiscall RConsole::Write(class TDesC16 const &)
+ ?PointerNumber@TConsoleKey@@QBEEXZ @ 33 NONAME ; public: unsigned char __thiscall TConsoleKey::PointerNumber(void)const
--- a/kernel/eka/bx86/ekernsmp.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86/ekernsmp.def Sun Mar 14 13:15:32 2010 +0000
@@ -999,4 +999,9 @@
?DestroyKernelMapObject@Kern@@SAXAAPAVTKernelMapObject@@@Z @ 998 NONAME ; public: static void __cdecl Kern::DestroyKernelMapObject(class TKernelMapObject * &)
?MapAndPinMemory@Kern@@SAHPAVTKernelMapObject@@PAVDThread@@KIIAAKPAK@Z @ 999 NONAME ; public: static int __cdecl Kern::MapAndPinMemory(class TKernelMapObject *,class DThread *,unsigned long,unsigned int,unsigned int,unsigned long &,unsigned long *)
?UnmapAndUnpinMemory@Kern@@SAXPAVTKernelMapObject@@@Z @ 1000 NONAME ; public: static void __cdecl Kern::UnmapAndUnpinMemory(class TKernelMapObject *)
+ ?AddTimingEntropy@Interrupt@@SAXXZ @ 1001 NONAME ; public: static void __cdecl Interrupt::AddTimingEntropy(void)
+ ?RandomSalt@Kern@@SAXKI@Z @ 1002 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned long,unsigned int)
+ ?RandomSalt@Kern@@SAX_KI@Z @ 1003 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned __int64,unsigned int)
+ ?RandomSalt@Kern@@SAXPBEII@Z @ 1004 NONAME ; void Kern::RandomSalt(unsigned char const *, unsigned int, unsigned int)
+ ?SecureRandom@Kern@@SAHAAVTDes8@@@Z @ 1005 NONAME ; int Kern::SecureRandom(class TDes8 &)
--- a/kernel/eka/bx86/ekernu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86/ekernu.def Sun Mar 14 13:15:32 2010 +0000
@@ -943,4 +943,9 @@
?DestroyKernelMapObject@Kern@@SAXAAPAVTKernelMapObject@@@Z @ 942 NONAME ; public: static void __cdecl Kern::DestroyKernelMapObject(class TKernelMapObject * &)
?MapAndPinMemory@Kern@@SAHPAVTKernelMapObject@@PAVDThread@@KIIAAKPAK@Z @ 943 NONAME ; public: static int __cdecl Kern::MapAndPinMemory(class TKernelMapObject *,class DThread *,unsigned long,unsigned int,unsigned int,unsigned long &,unsigned long *)
?UnmapAndUnpinMemory@Kern@@SAXPAVTKernelMapObject@@@Z @ 944 NONAME ; public: static void __cdecl Kern::UnmapAndUnpinMemory(class TKernelMapObject *)
+ ?AddTimingEntropy@Interrupt@@SAXXZ @ 945 NONAME ; public: static void __cdecl Interrupt::AddTimingEntropy(void)
+ ?RandomSalt@Kern@@SAXKI@Z @ 946 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned long,unsigned int)
+ ?RandomSalt@Kern@@SAX_KI@Z @ 947 NONAME ; public: static void __cdecl Kern::RandomSalt(unsigned __int64,unsigned int)
+ ?RandomSalt@Kern@@SAXPBEII@Z @ 948 NONAME ; void Kern::RandomSalt(unsigned char const *, unsigned int, unsigned int)
+ ?SecureRandom@Kern@@SAHAAVTDes8@@@Z @ 949 NONAME ; int Kern::SecureRandom(class TDes8 &)
--- a/kernel/eka/bx86/euseru.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86/euseru.def Sun Mar 14 13:15:32 2010 +0000
@@ -2179,4 +2179,8 @@
?LoadLocaleAspect@TExtendedLocale@@QAEHABVTDesC16@@@Z @ 2178 NONAME ; int TExtendedLocale::LoadLocaleAspect(class TDesC16 const &)
?RegionCode@User@@SA?AW4TRegionCode@@XZ @ 2179 NONAME ; enum TRegionCode User::RegionCode(void)
?SetReadOnly@TChunkCreateInfo@@QAEXXZ @ 2180 NONAME ; public: void __thiscall TChunkCreateInfo::SetReadOnly(void)
+ ?RandomL@Math@@SAXAAVTDes8@@@Z @ 2181 NONAME ; void Math::RandomL(class TDes8 &)
+ ?Random@Math@@SAXAAVTDes8@@@Z @ 2182 NONAME ; void Math::Random(class TDes8 &)
+ ?RandomL@Math@@SAKXZ @ 2183 NONAME ; unsigned long Math::RandomL(void)
+
--- a/kernel/eka/bx86gcc/ekernsmp.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86gcc/ekernsmp.def Sun Mar 14 13:15:32 2010 +0000
@@ -1087,4 +1087,9 @@
_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1086 NONAME
_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1087 NONAME
_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1088 NONAME
+ _ZN9Interrupt16AddTimingEntropyEv @ 1089 NONAME
+ _ZN4Kern10RandomSaltEmj @ 1090 NONAME
+ _ZN4Kern10RandomSaltEyj @ 1091 NONAME
+ _ZN4Kern10RandomSaltEPKhjj @ 1092 NONAME
+ _ZN4Kern12SecureRandomER5TDes8 @ 1093 NONAME
--- a/kernel/eka/bx86gcc/ekernu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86gcc/ekernu.def Sun Mar 14 13:15:32 2010 +0000
@@ -1026,4 +1026,9 @@
_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1025 NONAME
_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1026 NONAME
_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1027 NONAME
+ _ZN9Interrupt16AddTimingEntropyEv @ 1028 NONAME
+ _ZN4Kern10RandomSaltEmj @ 1029 NONAME
+ _ZN4Kern10RandomSaltEyj @ 1030 NONAME
+ _ZN4Kern10RandomSaltEPKhjj @ 1031 NONAME
+ _ZN4Kern12SecureRandomER5TDes8 @ 1032 NONAME
--- a/kernel/eka/bx86gcc/euseru.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/bx86gcc/euseru.def Sun Mar 14 13:15:32 2010 +0000
@@ -2458,3 +2458,6 @@
_ZN15TExtendedLocale10LoadLocaleERK7TDesC16S2_S2_ @ 2457 NONAME
_ZN15TExtendedLocale16LoadLocaleAspectERK7TDesC16 @ 2458 NONAME
_ZN16TChunkCreateInfo11SetReadOnlyEv @ 2459 NONAME
+ _ZN4Math7RandomLER5TDes8 @ 2460 NONAME
+ _ZN4Math6RandomER5TDes8 @ 2461 NONAME
+ _ZN4Math7RandomLEv @ 2462 NONAME
--- a/kernel/eka/compsupp/bld.inf Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/compsupp/bld.inf Sun Mar 14 13:15:32 2010 +0000
@@ -29,20 +29,6 @@
compsupp.iby /epoc32/rom/include/
-// Unzip runtimes not being built
-
-#if !defined(ARMCC_2_2)
-:zip rt_2_2_export.zip
-#endif
-
-#if !defined(ARMCC_3_1)
-:zip rt_3_1_export.zip
-#endif
-
-#if !defined(ARMCC_4_0)
-:zip rt_4_0_export.zip
-#endif
-
PRJ_MMPFILES
@@ -71,5 +57,22 @@
#endif
+PRJ_EXTENSIONS
+
+// Unzip RVCT3.1 runtime if being built with RVCT2.2 or RVCT4.0
+
+start extension tools/compsupp
+
+#if defined(ARMCC_2_2) || defined(ARMCC_4_0)
+option FILE $(EXTENSION_ROOT)/rt_3_1.zip
+#elif defined(ARMCC_3_1)
+option FILE $(EXTENSION_ROOT)/rt_2_2.zip
#endif
+option TODIR $(EPOCROOT)epoc32/release
+
+end
+
+#endif // #if !defined GCCXML && !defined GCCE
+
+
Binary file kernel/eka/compsupp/rt_2_2.zip has changed
Binary file kernel/eka/compsupp/rt_2_2_export.zip has changed
Binary file kernel/eka/compsupp/rt_3_1.zip has changed
Binary file kernel/eka/compsupp/rt_3_1_export.zip has changed
Binary file kernel/eka/compsupp/rt_4_0_export.zip has changed
--- a/kernel/eka/drivers/locmedia/locmedia.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/locmedia/locmedia.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -4947,8 +4947,10 @@
if (r != KErrNone)
{
- OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< retval=%d",r);
- return r;
+ OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< Caps::retval=%d - return KErrNotSupported",r);
+ // Media driver failure; media maybe recoverable after boot.
+ // Can't register any page drives so return not supported.
+ return KErrNotSupported;
}
TLocDrv* drive;
@@ -5012,7 +5014,7 @@
Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber);
Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber);
Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize);
- #endif
+#endif
// This table is indexed by DPagingDevice::TType
--- a/kernel/eka/drivers/media/base_e32_drivers_media.mrp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/media/base_e32_drivers_media.mrp Sun Mar 14 13:15:32 2010 +0000
@@ -23,8 +23,6 @@
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\stackbody.cpp
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\stackbody.h
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\distribution.policy.s60
-source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\Obtaining_PSL_Software_Source_Code.txt
-source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\distribution.policy.s60
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\sdcard3c\sdcard.cpp
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\sdcard3c\epbussd.mmp
source \sf\os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\sdcard3c\distribution.policy.s60
--- a/kernel/eka/drivers/medmmc/bgahsmmcptn.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/medmmc/bgahsmmcptn.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -119,7 +119,7 @@
}
else if ( PartitionIsFAT(aDrive.iPartitionType) || PartitionIsFAT32(aDrive.iPartitionType) )
{
- Info().iDriveAtt = iPartitionAttributes[aDrive.iPartitionNumber];
+ Info().iDriveAtt |= iPartitionAttributes[aDrive.iPartitionNumber];
}
return KErrNone;
--- a/kernel/eka/drivers/pbus/mmc/sdcard/Obtaining_PSL_Software_Source_Code.txt Mon Mar 08 11:57:08 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-The distribution of the SD Card PIL and PSL Software Source Code
-and Documentation is subject to the relevant party entering into
-the necessary agreement(s) with SD-3C LLC and/or 4C LLC.
-
-PIL Software Source Code for Symbian OS is distributed in the
-sdcard3c and sdcard4c subdirectories of this directory.
-PSL source code for special SD card hardware fitted to an
-ARM Integrator development board is distributed in sdcard3c
-and sdcard4c subdirectories within the Integrator component.
-If you have not received this source code, then you can obtain
-it from Symbian after proving that you have made the appropriate
-agreement(s).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/epbusmu.def Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,147 @@
+EXPORTS
+ _ZN10DMMCSocket5PanicENS_9TMMCPanicE @ 1 NONAME ; DMMCSocket::Panic(DMMCSocket::TMMCPanic)
+ _ZN10DMMCSocketC1EiP17TMMCPasswordStore @ 2 NONAME ; DMMCSocket::DMMCSocket(int, TMMCPasswordStore*)
+ _ZN10DMMCSocketC2EiP17TMMCPasswordStore @ 3 NONAME ; DMMCSocket::DMMCSocket(int, TMMCPasswordStore*)
+ _ZN11DMMCSession12SetupCommandE15TMMCCommandEnum12TMMCArgument @ 4 NONAME ; DMMCSession::SetupCommand(TMMCCommandEnum, TMMCArgument)
+ _ZN11DMMCSession14SetupCIMReadIOEhmPh @ 5 NONAME ; DMMCSession::SetupCIMReadIO(unsigned char, unsigned long, unsigned char*)
+ _ZN11DMMCSession14SetupDTCommandE15TMMCCommandEnum12TMMCArgumentmPhmi14TMMCCmdDirEnumm @ 6 NONAME ; DMMCSession::SetupDTCommand(TMMCCommandEnum, TMMCArgument, unsigned long, unsigned char*, unsigned long, int, TMMCCmdDirEnum, unsigned long)
+ _ZN11DMMCSession14SetupRSCommandE15TMMCCommandEnum12TMMCArgumentm19TMMCCommandTypeEnum20TMMCResponseTypeEnumm @ 7 NONAME ; DMMCSession::SetupRSCommand(TMMCCommandEnum, TMMCArgument, unsigned long, TMMCCommandTypeEnum, TMMCResponseTypeEnum, unsigned long)
+ _ZN11DMMCSession15FillCommandArgsE12TMMCArgumentmPhm @ 8 NONAME ; DMMCSession::FillCommandArgs(TMMCArgument, unsigned long, unsigned char*, unsigned long)
+ _ZN11DMMCSession15FillCommandDescE15TMMCCommandEnum @ 9 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum)
+ _ZN11DMMCSession15FillCommandDescE15TMMCCommandEnum12TMMCArgument @ 10 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum, TMMCArgument)
+ _ZN11DMMCSession15FillCommandDescEv @ 11 NONAME ; DMMCSession::FillCommandDesc()
+ _ZN11DMMCSession15SetupCIMWriteIOEhmPh @ 12 NONAME ; DMMCSession::SetupCIMWriteIO(unsigned char, unsigned long, unsigned char*)
+ _ZN11DMMCSession17SetupCIMReadBlockE12TMMCArgumentmPh @ 13 NONAME ; DMMCSession::SetupCIMReadBlock(TMMCArgument, unsigned long, unsigned char*)
+ _ZN11DMMCSession18SetupCIMEraseGroupE12TMMCArgumentm @ 14 NONAME ; DMMCSession::SetupCIMEraseGroup(TMMCArgument, unsigned long)
+ _ZN11DMMCSession18SetupCIMLockUnlockEmPh @ 15 NONAME ; DMMCSession::SetupCIMLockUnlock(unsigned long, unsigned char*)
+ _ZN11DMMCSession18SetupCIMReadMBlockE12TMMCArgumentmPhm @ 16 NONAME ; DMMCSession::SetupCIMReadMBlock(TMMCArgument, unsigned long, unsigned char*, unsigned long)
+ _ZN11DMMCSession18SetupCIMWriteBlockE12TMMCArgumentmPh @ 17 NONAME ; DMMCSession::SetupCIMWriteBlock(TMMCArgument, unsigned long, unsigned char*)
+ _ZN11DMMCSession19SetupCIMEraseSectorE12TMMCArgumentm @ 18 NONAME ; DMMCSession::SetupCIMEraseSector(TMMCArgument, unsigned long)
+ _ZN11DMMCSession19SetupCIMWriteMBlockE12TMMCArgumentmPhm @ 19 NONAME ; DMMCSession::SetupCIMWriteMBlock(TMMCArgument, unsigned long, unsigned char*, unsigned long)
+ _ZN11DMMCSession6EngageEv @ 20 NONAME ; DMMCSession::Engage()
+ _ZN11DMMCSession7CardRCAEv @ 21 NONAME ; DMMCSession::CardRCA()
+ _ZN11DMMCSession7SetCardEP7TMMCard @ 22 NONAME ; DMMCSession::SetCard(TMMCard*)
+ _ZN11DMMCSessionC1ERK12TMMCCallBack @ 23 NONAME ; DMMCSession::DMMCSession(TMMCCallBack const&)
+ _ZN11DMMCSessionC2ERK12TMMCCallBack @ 24 NONAME ; DMMCSession::DMMCSession(TMMCCallBack const&)
+ _ZN11DMMCSessionD0Ev @ 25 NONAME ; DMMCSession::~DMMCSession()
+ _ZN11DMMCSessionD1Ev @ 26 NONAME ; DMMCSession::~DMMCSession()
+ _ZN11DMMCSessionD2Ev @ 27 NONAME ; DMMCSession::~DMMCSession()
+ _ZN11DPBusSocket10InCriticalEv @ 28 NONAME ; DPBusSocket::InCritical()
+ _ZN11DPBusSocket12SocketFromIdEi @ 29 NONAME ; DPBusSocket::SocketFromId(int)
+ _ZN11DPBusSocket13EndInCriticalEv @ 30 NONAME ; DPBusSocket::EndInCritical()
+ _ZN11DPBusSocket16ForceMediaChangeEv @ 31 NONAME ; DPBusSocket::ForceMediaChange()
+ _ZN11DPBusSocket17PowerDownCompleteEv @ 32 NONAME ; DPBusSocket::PowerDownComplete()
+ _ZN11DPBusSocket21RequestAsyncPowerDownEv @ 33 NONAME ; DPBusSocket::RequestAsyncPowerDown()
+ _ZN11DPBusSocket23DeltaCurrentConsumptionEi @ 34 NONAME ; DPBusSocket::DeltaCurrentConsumption(int)
+ _ZN11DPBusSocket23PowerUpSequenceCompleteEi @ 35 NONAME ; DPBusSocket::PowerUpSequenceComplete(int)
+ _ZN11DPBusSocket3AddEP13TPBusCallBack @ 36 NONAME ; DPBusSocket::Add(TPBusCallBack*)
+ _ZN11DPBusSocket5PanicENS_6TPanicE @ 37 NONAME ; DPBusSocket::Panic(DPBusSocket::TPanic)
+ _ZN11DPBusSocket7PowerUpEv @ 38 NONAME ; DPBusSocket::PowerUp()
+ _ZN12DPBusPsuBase13DoTickServiceEv @ 39 NONAME ; DPBusPsuBase::DoTickService()
+ _ZN12DPBusPsuBase25ReceiveVoltageCheckResultEi @ 40 NONAME ; DPBusPsuBase::ReceiveVoltageCheckResult(int)
+ _ZN12DPBusPsuBase8DoCreateEv @ 41 NONAME ; DPBusPsuBase::DoCreate()
+ _ZN12DPBusPsuBase8IsLockedEv @ 42 NONAME ; DPBusPsuBase::IsLocked()
+ _ZN12DPBusPsuBase8SetStateE13TPBusPsuState @ 43 NONAME ; DPBusPsuBase::SetState(TPBusPsuState)
+ _ZN12TMMCardArray10AddNewCardEPKhP4TRCA @ 44 NONAME ; TMMCardArray::AddNewCard(unsigned char const*, TRCA*)
+ _ZN12TMMCardArray10AllocCardsEv @ 45 NONAME ; TMMCardArray::AllocCards()
+ _ZN12TMMCardArray17DeclareCardAsGoneEj @ 46 NONAME ; TMMCardArray::DeclareCardAsGone(unsigned int)
+ _ZN13TPBusCallBack6RemoveEv @ 47 NONAME ; TPBusCallBack::Remove()
+ _ZN13TPBusCallBack9SetSocketEi @ 48 NONAME ; TPBusCallBack::SetSocket(int)
+ _ZN13TPBusCallBackC1EPFvPviES0_j @ 49 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void*, int), void*, unsigned int)
+ _ZN13TPBusCallBackC1EPFvPviS0_S0_ES0_ @ 50 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void*, int, void*, void*), void*)
+ _ZN13TPBusCallBackC1Ev @ 51 NONAME ; TPBusCallBack::TPBusCallBack()
+ _ZN13TPBusCallBackC2EPFvPviES0_j @ 52 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void*, int), void*, unsigned int)
+ _ZN13TPBusCallBackC2EPFvPviS0_S0_ES0_ @ 53 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void*, int, void*, void*), void*)
+ _ZN13TPBusCallBackC2Ev @ 54 NONAME ; TPBusCallBack::TPBusCallBack()
+ _ZN15DMMCMediaChange6CreateEv @ 55 NONAME ; DMMCMediaChange::Create()
+ _ZN15DMMCMediaChangeC2Ei @ 56 NONAME ; DMMCMediaChange::DMMCMediaChange(int)
+ _ZN16DMediaChangeBase15DoorOpenServiceEv @ 57 NONAME ; DMediaChangeBase::DoorOpenService()
+ _ZN16DMediaChangeBase17DoorClosedServiceEv @ 58 NONAME ; DMediaChangeBase::DoorClosedService()
+ _ZN16DMediaChangeBase6CreateEv @ 59 NONAME ; DMediaChangeBase::Create()
+ _ZN16DMediaChangeBaseC2Ei @ 60 NONAME ; DMediaChangeBase::DMediaChangeBase(int)
+ _ZN16TMMCStateMachine4JumpEPFmPvEi @ 61 NONAME ; TMMCStateMachine::Jump(unsigned long (*)(void*), int)
+ _ZN16TMMCStateMachine4PushEPFmPvEi @ 62 NONAME ; TMMCStateMachine::Push(unsigned long (*)(void*), int)
+ _ZN16TMMCStateMachine5ResetEv @ 63 NONAME ; TMMCStateMachine::Reset()
+ _ZN16TMMCStateMachine8DispatchEv @ 64 NONAME ; TMMCStateMachine::Dispatch()
+ _ZN17TMMCPasswordStore18IsMappingIncorrectERK4TCIDRK5TBuf8ILi16EE @ 65 NONAME ; TMMCPasswordStore::IsMappingIncorrect(TCID const&, TBuf8<16> const&)
+ _ZN26TMMCardControllerInterface20RegisterMediaDevicesEi @ 66 NONAME ; TMMCardControllerInterface::RegisterMediaDevices(int)
+ _ZN26TMMCardControllerInterface6CreateEv @ 67 NONAME ; TMMCardControllerInterface::Create()
+ _ZN7DMMCPsu8DoCreateEv @ 68 NONAME ; DMMCPsu::DoCreate()
+ _ZN7DMMCPsuC2Eii @ 69 NONAME ; DMMCPsu::DMMCPsu(int, int)
+ _ZN9DMMCStack10CardDetectEj @ 70 NONAME ; DMMCStack::CardDetect(unsigned int)
+ _ZN9DMMCStack12PowerUpStackEv @ 71 NONAME ; DMMCStack::PowerUpStack()
+ _ZN9DMMCStack14AcquireStackSMEv @ 72 NONAME ; DMMCStack::AcquireStackSM()
+ _ZN9DMMCStack14EffectiveModesERK15TMMCStackConfig @ 73 NONAME ; DMMCStack::EffectiveModes(TMMCStackConfig const&)
+ _ZN9DMMCStack14PowerDownStackEv @ 74 NONAME ; DMMCStack::PowerDownStack()
+ _ZN9DMMCStack14WriteProtectedEj @ 75 NONAME ; DMMCStack::WriteProtected(unsigned int)
+ _ZN9DMMCStack19IssueMMCCommandSMSTEPv @ 76 NONAME ; DMMCStack::IssueMMCCommandSMST(void*)
+ _ZN9DMMCStack20CIMReadWriteBlocksSMEv @ 77 NONAME ; DMMCStack::CIMReadWriteBlocksSM()
+ _ZN9DMMCStack22CIMReadWriteBlocksSMSTEPv @ 78 NONAME ; DMMCStack::CIMReadWriteBlocksSMST(void*)
+ _ZN9DMMCStack22InitStackAfterUnlockSMEv @ 79 NONAME ; DMMCStack::InitStackAfterUnlockSM()
+ _ZN9DMMCStack4InitEv @ 80 NONAME ; DMMCStack::Init()
+ _ZN9DMMCStack4StopEP7TMMCard @ 81 NONAME ; DMMCStack::Stop(TMMCard*)
+ _ZN9DMMCStack5BlockEP11DMMCSessionm @ 82 NONAME ; DMMCStack::Block(DMMCSession*, unsigned long)
+ _ZN9DMMCStack7UnBlockEP11DMMCSessionmm @ 83 NONAME ; DMMCStack::UnBlock(DMMCSession*, unsigned long, unsigned long)
+ _ZN9DMMCStackC2EiP10DMMCSocket @ 84 NONAME ; DMMCStack::DMMCStack(int, DMMCSocket*)
+ _ZNK11DMMCSession13EpocErrorCodeEv @ 85 NONAME ; DMMCSession::EpocErrorCode() const
+ _ZNK11DMMCSession8GetMacroEi @ 86 NONAME ; DMMCSession::GetMacro(int) const
+ _ZNK15TMMCCommandDesc9DirectionEv @ 87 NONAME ; TMMCCommandDesc::Direction() const
+ _ZNK4TCSD10DeviceSizeEv @ 88 NONAME ; TCSD::DeviceSize() const
+ _ZNK4TCSD14EraseGroupSizeEv @ 89 NONAME ; TCSD::EraseGroupSize() const
+ _ZNK4TCSD15EraseSectorSizeEv @ 90 NONAME ; TCSD::EraseSectorSize() const
+ _ZNK4TCSD15ReadBlockLengthEv @ 91 NONAME ; TCSD::ReadBlockLength() const
+ _ZNK4TCSD16WriteBlockLengthEv @ 92 NONAME ; TCSD::WriteBlockLength() const
+ _ZNK4TCSD23MaxTranSpeedInKilohertzEv @ 93 NONAME ; TCSD::MaxTranSpeedInKilohertz() const
+ _ZNK4TCSD25MaxReadCurrentInMilliampsEv @ 94 NONAME ; TCSD::MaxReadCurrentInMilliamps() const
+ _ZNK4TCSD25MinReadCurrentInMilliampsEv @ 95 NONAME ; TCSD::MinReadCurrentInMilliamps() const
+ _ZNK4TCSD26MaxWriteCurrentInMilliampsEv @ 96 NONAME ; TCSD::MaxWriteCurrentInMilliamps() const
+ _ZNK4TCSD26MinWriteCurrentInMilliampsEv @ 97 NONAME ; TCSD::MinWriteCurrentInMilliamps() const
+ _ZNK4TCSD8CSDFieldERKjS1_ @ 98 NONAME ; TCSD::CSDField(unsigned int const&, unsigned int const&) const
+ _ZNK4TCSD9MediaTypeEv @ 99 NONAME ; TCSD::MediaType() const
+ _ZNK7TMMCard7IsReadyEv @ 100 NONAME ; TMMCard::IsReady() const
+ _ZNK7TMMCard8IsLockedEv @ 101 NONAME ; TMMCard::IsLocked() const
+ _ZNK9DMMCStack12AllocSessionERK12TMMCCallBack @ 102 NONAME ; DMMCStack::AllocSession(TMMCCallBack const&) const
+ _ZTI10DMMCSocket @ 103 NONAME ; typeinfo for DMMCSocket
+ _ZTI11DMMCSession @ 104 NONAME ; typeinfo for DMMCSession
+ _ZTI12DPBusPsuBase @ 105 NONAME ; typeinfo for DPBusPsuBase
+ _ZTI12TMMCardArray @ 106 NONAME ; typeinfo for TMMCardArray
+ _ZTI15DMMCMediaChange @ 107 NONAME ; typeinfo for DMMCMediaChange
+ _ZTI16DMediaChangeBase @ 108 NONAME ; typeinfo for DMediaChangeBase
+ _ZTI26TMMCardControllerInterface @ 109 NONAME ; typeinfo for TMMCardControllerInterface
+ _ZTI7DMMCPsu @ 110 NONAME ; typeinfo for DMMCPsu
+ _ZTI9DMMCStack @ 111 NONAME ; typeinfo for DMMCStack
+ _ZTV10DMMCSocket @ 112 NONAME ; vtable for DMMCSocket
+ _ZTV11DMMCSession @ 113 NONAME ; vtable for DMMCSession
+ _ZTV12DPBusPsuBase @ 114 NONAME ; vtable for DPBusPsuBase
+ _ZTV12TMMCardArray @ 115 NONAME ; vtable for TMMCardArray
+ _ZTV15DMMCMediaChange @ 116 NONAME ; vtable for DMMCMediaChange
+ _ZTV16DMediaChangeBase @ 117 NONAME ; vtable for DMediaChangeBase
+ _ZTV26TMMCardControllerInterface @ 118 NONAME ; vtable for TMMCardControllerInterface
+ _ZTV7DMMCPsu @ 119 NONAME ; vtable for DMMCPsu
+ _ZTV9DMMCStack @ 120 NONAME ; vtable for DMMCStack
+ _ZN9DMMCStack22ModifyCardCapabilitySMEv @ 121 NONAME ; DMMCStack::ModifyCardCapabilitySM()
+ _ZN9DMMCStack6Dummy1Ev @ 122 NONAME
+ _ZN9DMMCStack12GetInterfaceENS_12TInterfaceIdERPNS_10MInterfaceE @ 123 NONAME
+ _ZN9DMMCStack11MachineInfoER5TDes8 @ 124 NONAME
+ _ZN9DMMCStack11SetBusWidthEm @ 125 NONAME
+ _ZN11DPBusSocket9ControlIOEiPvS0_ @ 126 NONAME
+ _ZN12TSDCardArray10AllocCardsEv @ 127 NONAME
+ _ZN12TSDCardArray17DeclareCardAsGoneEj @ 128 NONAME
+ _ZN8DSDStack14AcquireStackSMEv @ 129 NONAME
+ _ZN8DSDStack20CIMReadWriteBlocksSMEv @ 130 NONAME
+ _ZN8DSDStack22InitStackAfterUnlockSMEv @ 131 NONAME
+ _ZN8DSDStack22ModifyCardCapabilitySMEv @ 132 NONAME
+ _ZN8DSDStack4InitEv @ 133 NONAME
+ _ZN8DSDStack6Dummy1Ev @ 134 NONAME
+ _ZN8DSDStack6Dummy2Ev @ 135 NONAME
+ _ZN8DSDStack6Dummy3Ev @ 136 NONAME
+ _ZN8DSDStack8CardTypeEii @ 137 NONAME
+ _ZNK8DSDStack12AllocSessionERK12TMMCCallBack @ 138 NONAME
+ _ZTI12TSDCardArray @ 139 NONAME ; #<TI>#
+ _ZTI7TSDCard @ 140 NONAME ; #<TI>#
+ _ZTI8DSDStack @ 141 NONAME ; #<TI>#
+ _ZTV12TSDCardArray @ 142 NONAME ; #<VT>#
+ _ZTV7TSDCard @ 143 NONAME ; #<VT>#
+ _ZTV8DSDStack @ 144 NONAME ; #<VT>#
+
+
\ No newline at end of file
--- a/kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/sdio/epbusmu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/sdio/epbusmu.def Sun Mar 14 13:15:32 2010 +0000
@@ -135,7 +135,7 @@
_ZN8DSDStack6Dummy1Ev @ 134 NONAME
_ZN8DSDStack6Dummy2Ev @ 135 NONAME
_ZN8DSDStack6Dummy3Ev @ 136 NONAME
- _ZN8DSDStack6Dummy4Ev @ 137 NONAME
+ _ZN8DSDStack8CardTypeEii @ 137 NONAME
_ZNK8DSDStack12AllocSessionERK12TMMCCallBack @ 138 NONAME
_ZTI12TSDCardArray @ 139 NONAME ; #<TI>#
_ZTI7TSDCard @ 140 NONAME ; #<TI>#
--- a/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdcard.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdcard.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -16,7 +16,7 @@
#include <drivers/sdcard.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "locmedia_ost.h"
+#include "../../../../include/drivers/locmedia_ost.h"
#ifdef __VC32__
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
#endif
@@ -594,8 +594,16 @@
SMF_BEGIN
- OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM1, "EStBegin" );
- iCxCardType = ESDCardTypeUnknown;
+ OstTrace0( TRACE_INTERNALS, DSDSTACK_INITIALISEMEMORYCARDSM1, "EStBegin" );
+
+ iCxCardType = CardType(MMCSocket()->iSocketNumber, iCxCardCount);
+
+ if (iCxCardType==ESDCardTypeIsMMC)
+ {
+ // Skip the SD Protocol Seq.
+ SMF_INVOKES(GoIdleSMST, EStCheckVoltage);
+ }
+
s.iCardP = NULL; // This stops ExecCommandSM() from setting old RCA when sending CMD55
// Send CMD0 to initialise memory
@@ -1623,7 +1631,22 @@
return new DSDSession(aCallBack);
}
+EXPORT_C DSDStack::TSDCardType DSDStack::CardType(TInt /*aSocket*/, TInt /*aCardNumber*/)
+/**
+ * This method allows a preset card type to be specified for a given slot/socket.
+ * The SD protocol stack attempts to identify card types (SD or MMC) through protocol responses;
+ * For embedded media (eMMC or eSD) this is unnecessary as the media type is already known and cannot change.
+ * Licensee may override this function to specify the preset card type.
+ * @param aSocket Socket to be queried for card type.
+ * @param aCardNumber Card number attached to Socket to be queried for card type.
+ * @return Preset card type
+ */
+ {
+ // Default implmentation.
+ return DSDStack::ESDCardTypeUnknown;
+ }
+
+
EXPORT_C void DSDStack::Dummy1() {}
EXPORT_C void DSDStack::Dummy2() {}
EXPORT_C void DSDStack::Dummy3() {}
-EXPORT_C void DSDStack::Dummy4() {}
--- a/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/sdiostack.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/sdiostack.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -165,6 +165,14 @@
{
SMF_GOTOS(EStCheckNextCard)
}
+
+ iCxCardType = CardType(MMCSocket()->iSocketNumber, iCxCardCount);
+
+ if (iCxCardType!=ESDCardTypeUnknown)
+ {
+ // Skip the SDIO Protocol Seq.
+ SMF_GOTOS(EStInitMemoryCard);
+ }
TRACE2(TTraceContext(EBorder), UTraceModuleEPBusSDIO::ESDIODSDIOStackPSLCalledAddressCard, reinterpret_cast<TUint32>(this), iCxCardCount); // @SymTraceDataPublishedTvk
AddressCard(iCxCardCount);
--- a/kernel/eka/drivers/pbus/mmc/session.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/mmc/session.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -16,7 +16,7 @@
#include <drivers/mmc.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "locmedia_ost.h"
+#include "../../../include/drivers/locmedia_ost.h"
#ifdef __VC32__
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
#endif
--- a/kernel/eka/drivers/pbus/mmc/stack.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/mmc/stack.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -22,7 +22,7 @@
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "locmedia_ost.h"
+#include "../../../include/drivers/locmedia_ost.h"
#ifdef __VC32__
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
#endif
--- a/kernel/eka/drivers/pbus/pbusmedia.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/pbusmedia.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -18,7 +18,7 @@
#include <drivers/pbusmedia.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "locmedia_ost.h"
+#include "../../include/drivers/locmedia_ost.h"
#ifdef __VC32__
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
#endif
--- a/kernel/eka/drivers/pbus/spbus.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/pbus/spbus.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -18,7 +18,7 @@
#include <drivers/pbus.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
-#include "locmedia_ost.h"
+#include "../../include/drivers/locmedia_ost.h"
#ifdef __VC32__
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
#endif
--- a/kernel/eka/drivers/usbc/d_usbc.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/usbc/d_usbc.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -153,6 +153,7 @@
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::~DLddUsbcChannel()"));
if (iController)
{
+ iController->DeRegisterClient(this);
iStatusCallbackInfo.Cancel();
iEndpointStatusCallbackInfo.Cancel();
iOtgFeatureCallbackInfo.Cancel();
@@ -164,7 +165,6 @@
iController->ReleaseDeviceControl(this);
iOwnsDeviceControl = EFalse;
}
- iController->DeRegisterClient(this);
DestroyEp0();
delete iStatusFifo;
Kern::DestroyClientRequest(iStatusChangeReq);
--- a/kernel/eka/drivers/usbcc/ps_usbc.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/usbcc/ps_usbc.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -672,14 +672,14 @@
#ifdef USB_OTG_CLIENT
iClientSupportReady = ETrue;
const TInt r = EvaluateOtgConnectFlags();
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
if (iUsbResetDeferred) // implies (iOtgHnpHandledByHw == ETrue)
{
__KTRACE_OPT(KUSB, Kern::Printf(" Resetting USB Reset 'defer' flag"));
iUsbResetDeferred = EFalse;
(void) ProcessResetEvent(EFalse);
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
#else
const TInt r = UdcConnect();
#endif // USB_OTG_CLIENT
@@ -743,9 +743,9 @@
__KTRACE_OPT(KUSB, Kern::Printf(" Error: StatusCallback @ 0x%x already registered", &aCallback));
return KErrGeneral;
}
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
iStatusCallbacks.AddLast(aCallback);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
@@ -761,7 +761,7 @@
{
__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForStatusChange()"));
__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
TUsbcStatusCallback* p;
while ((p = iter++) != NULL)
@@ -770,12 +770,12 @@
{
__KTRACE_OPT(KUSB, Kern::Printf(" removing StatusCallback @ 0x%x", p));
iStatusCallbacks.Remove(*p);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
}
__KTRACE_OPT(KUSB, Kern::Printf(" client not found"));
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNotFound;
}
@@ -809,9 +809,9 @@
__KTRACE_OPT(KUSB, Kern::Printf(" Error: EpStatusCallback @ 0x%x already registered", &aCallback));
return KErrGeneral;
}
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
iEpStatusCallbacks.AddLast(aCallback);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
@@ -827,7 +827,7 @@
{
__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForEndpointStatusChange()"));
__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
TUsbcEndpointStatusCallback* p;
while ((p = iter++) != NULL)
@@ -836,12 +836,12 @@
{
__KTRACE_OPT(KUSB, Kern::Printf(" removing EpStatusCallback @ 0x%x", p));
iEpStatusCallbacks.Remove(*p);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
}
__KTRACE_OPT(KUSB, Kern::Printf(" client not found"));
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNotFound;
}
@@ -1056,17 +1056,17 @@
}
// Ep0 reads don't need to be prepared - there's always one pending
__KTRACE_OPT(KUSB, Kern::Printf(" adding RequestCallback @ 0x%x (ep0)", &aCallback));
- TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
iEp0ReadRequestCallbacks.AddLast(aCallback);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
err = KErrNone;
if (iEp0_RxExtraData)
{
__KTRACE_OPT(KUSB, Kern::Printf(" iEp0_RxExtraData: trying again..."));
const TBool rx_data = iEp0DataReceiving;
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
err = ProcessEp0ReceiveDone(iEp0_RxExtraCount);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
if (err == KErrNone)
{
iEp0_RxExtraData = EFalse;
@@ -1643,9 +1643,9 @@
__KTRACE_OPT(KUSB, Kern::Printf(" Error: OtgFeatureCallback @ 0x%x already registered", &aCallback));
return KErrAlreadyExists;
}
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
iOtgCallbacks.AddLast(aCallback);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
@@ -1661,7 +1661,7 @@
{
__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForOtgFeatureChange()"));
__ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
TUsbcOtgFeatureCallback* p;
while ((p = iter++) != NULL)
@@ -1670,12 +1670,12 @@
{
__KTRACE_OPT(KUSB, Kern::Printf(" removing OtgFeatureCallback @ 0x%x", p));
iOtgCallbacks.Remove(*p);
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNone;
}
}
__KTRACE_OPT(KUSB, Kern::Printf(" client not found"));
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return KErrNotFound;
}
@@ -2881,6 +2881,7 @@
iOtgCallbacks(_FOFF(TUsbcOtgFeatureCallback, iLink)),
iReconnectTimer(ReconnectTimerCallback, this),
iCableStatusTimer(CableStatusTimerCallback, this),
+ iUsbLock(TSpinLock::EOrderGenericIrqLow3),
iPowerUpDfc(PowerUpDfc, this, 3),
iPowerDownDfc(PowerDownDfc, this, 3),
iStandby(EFalse),
@@ -3765,7 +3766,7 @@
// Ep0 OUT
if (aEndpointNum == 0)
{
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
TUsbcRequestCallback* p;
while ((p = iter++) != NULL)
@@ -3778,7 +3779,7 @@
iEp0ReadRequestCallbacks.Remove(*p);
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return;
}
// Other endpoints
@@ -3798,7 +3799,7 @@
// aClientId being NULL means: delete all requests for *all* clients.
__KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallbacks()"));
// Ep0 OUT
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
TUsbcRequestCallback* p;
while ((p = iter++) != NULL)
@@ -3809,7 +3810,7 @@
iEp0ReadRequestCallbacks.Remove(*p);
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
// Other endpoints
for (TInt i = 1; i < KUsbcEpArraySize; i++)
{
@@ -4278,7 +4279,23 @@
// notification in any case, even if no cable and/or host are
// connected. The next Reset will get us out of it again.
iDeviceStateB4Suspend = iDeviceState;
- NextDeviceState(EUsbcDeviceStateSuspended);
+ // Please pay attention to that the above comment now is not accurate!
+ // It's not updated according the below modification just for keeping the original comment!
+ //
+ // Moving to Suspend state arbitrarily will cause DEFECT EDHO-7Y3AAD.
+ // DEFECT EDHO-7Y3AAD: Connected to the USB Charger, the UI displayed wrongly connected as default mode
+ // since the iDeviceState changed wrongly from Undefined to Suspended, and keep
+ // always Suspended becauseof NO Reset coming next!
+ // So, to fix this defect, the state change notification is modified to be triggerred by loop the current state again
+ // if the current state is Undefined!
+ if (EUsbcDeviceStateUndefined != iDeviceState)
+ {
+ NextDeviceState(EUsbcDeviceStateSuspended);
+ }
+ else
+ {
+ NextDeviceState(iDeviceState);
+ }
r = (*iEnablePullUpOnDPlus)(iOtgContext);
if (r != KErrNone)
{
--- a/kernel/eka/drivers/usbcsc/d_usbcsc.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/drivers/usbcsc/d_usbcsc.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1208,6 +1208,7 @@
__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcScChannel::~DLddUsbcScChannel()"));
if (iController)
{
+ iController->DeRegisterClient(this);
iStatusCallbackInfo.Cancel();
iEndpointStatusCallbackInfo.Cancel();
iOtgFeatureCallbackInfo.Cancel();
@@ -1218,7 +1219,6 @@
iController->ReleaseDeviceControl(this);
iOwnsDeviceControl = EFalse;
}
- iController->DeRegisterClient(this);
iController=NULL;
DestroyEp0();
if (iStatusFifo!=NULL)
--- a/kernel/eka/eabi/econs.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/eabi/econs.def Sun Mar 14 13:15:32 2010 +0000
@@ -31,4 +31,5 @@
_ZNK8RConsole10ScreenSizeER5TSize @ 30 NONAME ; RConsole::ScreenSize(TSize&) const
_ZNK8RConsole4SizeER5TSize @ 31 NONAME ; RConsole::Size(TSize&) const
_ZNK8RConsole9CursorPosER6TPoint @ 32 NONAME ; RConsole::CursorPos(TPoint&) const
+ _ZNK11TConsoleKey13PointerNumberEv @ 33 NONAME
--- a/kernel/eka/eabi/ekernsmp.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/eabi/ekernsmp.def Sun Mar 14 13:15:32 2010 +0000
@@ -1175,4 +1175,9 @@
_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1174 NONAME
_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1175 NONAME
_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1176 NONAME
+ _ZN9Interrupt16AddTimingEntropyEv @ 1177 NONAME
+ _ZN4Kern10RandomSaltEmj @ 1178 NONAME
+ _ZN4Kern10RandomSaltEyj @ 1179 NONAME
+ _ZN4Kern10RandomSaltEPKhjj @ 1180 NONAME
+ _ZN4Kern12SecureRandomER5TDes8 @ 1181 NONAME
--- a/kernel/eka/eabi/ekernu.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/eabi/ekernu.def Sun Mar 14 13:15:32 2010 +0000
@@ -1166,4 +1166,9 @@
_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1165 NONAME
_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1166 NONAME
_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1167 NONAME
+ _ZN9Interrupt16AddTimingEntropyEv @ 1168 NONAME
+ _ZN4Kern10RandomSaltEmj @ 1169 NONAME
+ _ZN4Kern10RandomSaltEyj @ 1170 NONAME
+ _ZN4Kern10RandomSaltEPKhjj @ 1171 NONAME
+ _ZN4Kern12SecureRandomER5TDes8 @ 1172 NONAME
--- a/kernel/eka/eabi/euseru.def Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/eabi/euseru.def Sun Mar 14 13:15:32 2010 +0000
@@ -2501,4 +2501,7 @@
_ZN15TExtendedLocale10LoadLocaleERK7TDesC16S2_S2_ @ 2500 NONAME
_ZN15TExtendedLocale16LoadLocaleAspectERK7TDesC16 @ 2501 NONAME
_ZN16TChunkCreateInfo11SetReadOnlyEv @ 2502 NONAME
+ _ZN4Math7RandomLER5TDes8 @ 2503 NONAME
+ _ZN4Math6RandomER5TDes8 @ 2504 NONAME
+ _ZN4Math7RandomLEv @ 2505 NONAME
--- a/kernel/eka/euser/us_exec.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/euser/us_exec.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -6358,7 +6358,14 @@
EXPORT_C TUint32 Math::Random()
/**
-Gets 32 random bits from the kernel's random pool.
+Gets 32 random bits from the kernel's random number generator.
+
+The returned random data may or may not be cryptographically secure but should be of a high quality for
+non-cryptographic purposes.
+
+This function uses a cryptographically strong random number generator to generate the random data, which can
+be slower than insecure generators. If security is not important, a faster generator may be used such as
+Math::Rand().
@return The 32 random bits.
*/
@@ -6367,6 +6374,62 @@
return Exec::MathRandom();
}
+EXPORT_C void Math::Random(TDes8& aRandomValue)
+/**
+Fills the provided descriptor with random data up to its current length. The number of random bytes required
+should be specified by setting the length of the descriptor that is passed to this function.
+
+The returned random data may or may not be cryptographically secure but should be of a high quality for
+non-cryptographic purposes.
+
+This function uses a cryptographically strong random number generator to generate the random data, which can
+be slower than insecure generators. If security is not important, a faster generator may be used such as
+Math::Rand().
+
+@param aRandomValue on return, the descriptor is filled with the requested number of random bytes.
+*/
+ {
+ Exec::MathSecureRandom(aRandomValue);
+ }
+
+
+EXPORT_C void Math::RandomL(TDes8& aRandomValue)
+/**
+Fills the provided descriptor with random data up to its current length. The number of random bytes required
+should be specified by setting the length of the descriptor that is passed to the function.
+
+If the returned random data cannot be guaranteed to be cryptographically secure, the function will leave with
+KErrNotReady to indicate that the returned data should not be used for cryptographic purposes.
+
+The security strength of the cryptographically strong random number generator is 256 bits.
+
+@param aRandomValue on return, the descriptor is filled with the requested number of random bytes.
+
+@leave KErrNotReady if the returned random data cannot be guaranteed to be cryptographically secure.
+*/
+ {
+ User::LeaveIfError(Exec::MathSecureRandom(aRandomValue));
+ }
+
+EXPORT_C TUint32 Math::RandomL()
+/**
+Gets 32 random bits from the kernel's random number generator.
+
+If the returned random data could not be guaranteed to be cryptographically secure, the function will instead
+leave with KErrNotReady to indicate that data was not available.
+
+The security strength of the cryptographically strong random number generator is 256 bits.
+
+@leave KErrNotReady if no data was returned as it could not be guaranteed to be cryptographically secure.
+
+@return The 32 random bits.
+*/
+ {
+ TBuf8<sizeof(TUint32)> randomBuffer;
+ randomBuffer.SetMax();
+ User::LeaveIfError(Exec::MathSecureRandom(randomBuffer));
+ return *(TUint32*)(randomBuffer.Ptr());
+ }
EXPORT_C void User::IMB_Range(TAny* aStart, TAny* aEnd)
--- a/kernel/eka/ewsrv/co_utl.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/ewsrv/co_utl.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -44,6 +44,14 @@
return((*((TConsoleKey *)this))().iModifiers);
}
+EXPORT_C TUint8 TConsoleKey::PointerNumber() const
+//
+// Return the pointer number
+//
+ {
+ return((*((TConsoleKey *)this))().iPointerNumber);
+ }
+
EXPORT_C TInt TConsoleKey::Type() const
//
// Return the key type
--- a/kernel/eka/ewsrv/ws_win.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/ewsrv/ws_win.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -2170,6 +2170,7 @@
case TRawEvent::EButton3Down:
case TRawEvent::EButton3Up:
pS->iMousePos=anEvent.Pos();
+ pS->iPointerNumber = anEvent.PointerNumber();
break;
case TRawEvent::EKeyUp:
case TRawEvent::EKeyDown:
@@ -2433,6 +2434,7 @@
k.iModifiers=KeyTranslator->GetModifierState();
+ k.iPointerNumber = pS->iPointerNumber;
k.iType=pS->iType;
k.iMousePos=pS->iMousePos;
--- a/kernel/eka/generic.inf Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/generic.inf Sun Mar 14 13:15:32 2010 +0000
@@ -17,14 +17,18 @@
//
//
+PRJ_EXPORTS
+rombuild/rom.flm /epoc32/tools/makefile_templates/base/rom.flm
+rombuild/rom.meta /epoc32/tools/makefile_templates/base/rom.meta
+rombuild/rom.xml /epoc32/tools/makefile_templates/base/rom.xml
PRJ_EXTENSIONS
start extension base/genexec
#ifdef SYMBIAN_OLD_EXPORT_LOCATION
-option INC_PATH /epoc32/include
+option INC_PATH $(EPOCROOT)epoc32/include
#else
-option INC_PATH /epoc32/include/platform
+option INC_PATH $(EPOCROOT)epoc32/include/platform
#endif
--- a/kernel/eka/include/drivers/sdcard.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/drivers/sdcard.h Sun Mar 14 13:15:32 2010 +0000
@@ -151,7 +151,7 @@
IMPORT_C virtual TMMCErr AcquireStackSM();
IMPORT_C virtual TMMCErr CIMReadWriteBlocksSM();
IMPORT_C virtual DMMCSession* AllocSession(const TMMCCallBack& aCallBack) const;
-
+
virtual void AddressCard(TInt aCardNumber) = 0;
inline TSDCardArray& CardArray() const;
@@ -175,8 +175,10 @@
private:
TInt iSpare;
+protected:
enum TSDCardType {ESDCardTypeUnknown, ESDCardTypeIsMMC, ESDCardTypeIsSD};
TSDCardType iCxCardType; // Used when detecting whether an SD Memory card is present.
+private:
TUint8 iACMD22[KSDACMD22BlockLen];
private:
@@ -185,7 +187,11 @@
IMPORT_C virtual void Dummy1();
IMPORT_C virtual void Dummy2();
IMPORT_C virtual void Dummy3();
- IMPORT_C virtual void Dummy4();
+
+public:
+ IMPORT_C virtual DSDStack::TSDCardType CardType(TInt aSocket, TInt aCardNumber);
+
+private:
//
// Reserved members to maintain binary compatibility
TInt iReserved[68];
--- a/kernel/eka/include/drivers/usbcshared.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/drivers/usbcshared.h Sun Mar 14 13:15:32 2010 +0000
@@ -1598,6 +1598,7 @@
NTimer iReconnectTimer; // implements USB re-enumeration delay
NTimer iCableStatusTimer; // implements USB cable status detection delay
DUsbcPowerHandler* iPowerHandler; // pointer to USB power handler object
+ TSpinLock iUsbLock; // implement SMP for USB PDD and LDD
protected:
TDfc iPowerUpDfc; // queued by power handler upon power-up
--- a/kernel/eka/include/drivers/usbcshared.inl Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/drivers/usbcshared.inl Sun Mar 14 13:15:32 2010 +0000
@@ -132,72 +132,72 @@
TBool DUsbClientController::IsInTheRequestList(const TUsbcRequestCallback& aCallback)
{
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
TUsbcRequestCallback* p;
while ((p = iter++) != NULL)
{
if (p == &aCallback)
{
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return ETrue;
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return EFalse;
}
TBool DUsbClientController::IsInTheStatusList(const TUsbcStatusCallback& aCallback)
{
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
TUsbcStatusCallback* p;
while ((p = iter++) != NULL)
{
if (p == &aCallback)
{
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return ETrue;
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return EFalse;
}
TBool DUsbClientController::IsInTheEpStatusList(const TUsbcEndpointStatusCallback& aCallback)
{
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
TUsbcEndpointStatusCallback* p;
while ((p = iter++) != NULL)
{
if (p == &aCallback)
{
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return ETrue;
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return EFalse;
}
TBool DUsbClientController::IsInTheOtgFeatureList(const TUsbcOtgFeatureCallback& aCallback)
{
- const TInt irq = NKern::DisableAllInterrupts();
+ const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
TUsbcOtgFeatureCallback* p;
while ((p = iter++) != NULL)
{
if (p == &aCallback)
{
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return ETrue;
}
}
- NKern::RestoreInterrupts(irq);
+ __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
return EFalse;
}
--- a/kernel/eka/include/e32kpan.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/e32kpan.h Sun Mar 14 13:15:32 2010 +0000
@@ -503,6 +503,11 @@
An invalid parameter was passed to a shared buffers exec call handler.
*/
EShBufExecBadParameter=65,
+
+ /**
+ An entropy estimate passed to an entropy buffer was outside the allowed range.
+ */
+ EEntropyEstimateOutOfRange=66,
};
#endif
--- a/kernel/eka/include/e32math.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/e32math.h Sun Mar 14 13:15:32 2010 +0000
@@ -475,6 +475,9 @@
IMPORT_C static TInt Rand(TInt64 &aSeed);
IMPORT_C static TReal FRand(TInt64 &aSeed) __SOFTFP;
IMPORT_C static TUint32 Random();
+ IMPORT_C static void Random(TDes8& aRandomValue);
+ IMPORT_C static void RandomL(TDes8& aRandomValue);
+ IMPORT_C static TUint32 RandomL();
IMPORT_C static TInt Round(TReal &aTrg,const TReal &aSrc,TInt aDecimalPlaces);
IMPORT_C static TInt Sin(TReal &aTrg,const TReal &aSrc);
IMPORT_C static TInt Sqrt(TReal &aTrg,const TReal &aSrc);
--- a/kernel/eka/include/e32twin.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/e32twin.h Sun Mar 14 13:15:32 2010 +0000
@@ -56,6 +56,7 @@
TUint iModifiers;
TPoint iMousePos;
TInt iType;
+ TUint8 iPointerNumber;
};
/** @internalTechnology */
@@ -66,6 +67,7 @@
IMPORT_C TInt Modifiers() const;
IMPORT_C TInt Type() const;
IMPORT_C TPoint MousePos() const;
+ IMPORT_C TUint8 PointerNumber() const;
};
/** @internalTechnology */
--- a/kernel/eka/include/e32ver.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/e32ver.h Sun Mar 14 13:15:32 2010 +0000
@@ -28,7 +28,7 @@
const TInt KE32MajorVersionNumber=2;
const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=2066;
+const TInt KE32BuildVersionNumber=2075;
const TInt KMachineConfigurationMajorVersionNumber=1;
const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/include/kernel/arm/assp.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/arm/assp.h Sun Mar 14 13:15:32 2010 +0000
@@ -38,9 +38,10 @@
A class that exports interrupt functionality to device drivers and
other kernel-side code.
-Although Symbian OS defines this class, it does not implement it;
-an implementation for each of the functions defined by this class must
-be provided by the Variant in the baseport.
+Although Symbian OS defines this class, it does not implement the majority
+of it; an implementation for each of the functions defined by this class,
+with the exception of AddTimingEntropy, must be provided by the Variant in
+the baseport.
Note that the class only provides the public API for using interrupts,
not for dispatching them.
@@ -142,6 +143,16 @@
are not supported.
*/
IMPORT_C static TInt SetPriority(TInt anId, TInt aPriority);
+
+ /**
+ This function is implemented by the kernel. It adds the current, highest
+ resolution timestamp to the secure RNG's entropy pool.
+
+ It should be called from the ISR of any device where the timing of interrupts
+ would be considered random, for example the keyboard or digitiser drivers.
+ */
+
+ IMPORT_C static void AddTimingEntropy();
};
/**
--- a/kernel/eka/include/kernel/arm/bootdefs.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/arm/bootdefs.h Sun Mar 14 13:15:32 2010 +0000
@@ -138,12 +138,16 @@
/**
The most common values for BPR_Platform_Specific_Mappings boot parameter. Any *_Mapping5 value can be orred with any
-*_Mapping6 or *_Mapping7. For example:
+*_Mapping6 and/or *_Mapping7. For example:
@code
ParameterTable
- DCD BPR_Platform_Specific_Mappings, E_WT_WT_Mapping5 | E_FC_NC_Mapping6 | E_NC_FC_Mapping7
+ DCD BPR_Platform_Specific_Mappings, E_WT_WT_Mapping5+E_FC_NC_Mapping6+E_NC_FC_Mapping7
@codeend
-Where stated, "maximum caching" refers to write back read/write allocate if supported by platform.
+specifies:
+ - EMemAttPlatformSpecific5 to be write-through mapping in both inner and outer cache.
+ - EMemAttPlatformSpecific6 to be fully cached (write-back) in inner cache and not cached in outer cache.
+ - EMemAttPlatformSpecific7 to be not cached in inner cache and fully cached (write-back) in outer cache.
+
@see BPR_Platform_Specific_Mappings
@publishedPartner
@released
@@ -151,14 +155,20 @@
enum TPlatformSpecificMappings
{
E_WT_WT_Mapping5 = 0x08000802, /**Write Through caching on both levels for mapping #5.*/
+ E_WT_NC_Mapping5 = 0x00000802, /**Write Through caching at level 1, not cached at level 2 for mapping #5.*/
+ E_NC_WT_Mapping5 = 0x08000002, /**Not cached at level 1, Write Through cached at level for mapping #5.*/
E_FC_NC_Mapping5 = 0x00000402, /**Maximum caching at level 1, not cached at level 2 for mapping #5.*/
E_NC_FC_Mapping5 = 0x04000002, /**Not cached at level 1, maximum caching at level 2 for mapping #5.*/
E_WT_WT_Mapping6 = 0x20002008, /**Write Through caching on both levels for mapping #6.*/
+ E_WT_NC_Mapping6 = 0x00002008, /**Write Through caching at level 1, not cached at level 2 for mapping #6.*/
+ E_NC_WT_Mapping6 = 0x20000008, /**Not cached at level 1, Write Through cached at level for mapping #6.*/
E_FC_NC_Mapping6 = 0x00001008, /**Maximum caching at level 1, not cached at level 2 for mapping #6.*/
E_NC_FC_Mapping6 = 0x10000008, /**Not cached at level 1, maximum caching at level 2 for mapping #6.*/
E_WT_WT_Mapping7 = 0x80008020, /**Write Through caching on both levels for mapping #7.*/
+ E_WT_NC_Mapping7 = 0x00008020, /**Write Through caching at level 1, not cached at level 2 for mapping #7.*/
+ E_NC_WT_Mapping7 = 0x80000020, /**Not cached at level 1, Write Through cached at level for mapping #7.*/
E_FC_NC_Mapping7 = 0x00004020, /**Maximum caching at level 1, not cached at level 2 for mapping #7.*/
E_NC_FC_Mapping7 = 0x40000020, /**Not cached at level 1, maximum caching at level 2 for mapping #7.*/
};
--- a/kernel/eka/include/kernel/cache_maintenance.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/cache_maintenance.h Sun Mar 14 13:15:32 2010 +0000
@@ -43,6 +43,12 @@
const TInt KCacheInfoD=1; // InternalCache info for DCache. On ARMv7, this applies to the point-of-coherency.
const TInt KCacheInfoD_PoU=2; // InternalCache info for ARMv7 DCache for the point-of-unification.
+#if !defined(__CPU_MEMORY_TYPE_REMAPPING) && defined(__CPU_ARM)
+// These constants must be dthe same as DefaultPRRR & DefaultNMRR in bootcpu.inc
+const TUint32 KDefaultPrimaryRegionRemapRegister = 0x000a00a4;
+const TUint32 KDefaultNormalMemoryRemapRegister = 0x00400040;
+#endif
+
/*
* Cache info of particular cache type or level.
*/
@@ -100,7 +106,6 @@
/*
* @return Internal and external cache attributes (orred TMappingAttributes enums)
* that match aType memory type.
- * @panic: If aType 4-7 is specified on platform with no __CPU_MEMORY_TYPE_REMAPPING.
*/
static TUint32 TypeToCachingAttributes(TMemoryType aType);
@@ -323,7 +328,6 @@
static void ParseCacheSizeInfo(TUint32 aValue, SCacheInfo& aInfo);
#endif
-#if defined(__CPU_MEMORY_TYPE_REMAPPING)
/*
* @return The content of Primary Region Remap Register.
*/
@@ -333,11 +337,18 @@
* @return The content of Normal Memory Remap Register.
*/
static TUint32 NormalMemoryRemapRegister();
-#endif // defined(__CPU_MEMORY_TYPE_REMAPPING)
#if defined(__CPU_ARMV7)
static TInt DmaBufferAlignementLog2; // Holds the alignement requirement for DMA buffers.
#endif
+
+#if !defined(__CPU_MEMORY_TYPE_REMAPPING) && defined(__CPU_ARM)
+ /**
+ * On platforms with no memory type remapping, we have to simulate TMemoryType values 4-7
+ */
+ static TUint32 iPrimaryRegionRemapRegister;
+ static TUint32 iNormalMemoryRemapRegister;
+#endif
};
#ifdef __HAS_EXTERNAL_CACHE__
--- a/kernel/eka/include/kernel/kern_priv.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/kern_priv.h Sun Mar 14 13:15:32 2010 +0000
@@ -62,6 +62,9 @@
#endif
#endif
+// size of each buffer used to store entropy data before it is passed to the RNG
+const TUint KEntropyBufferSizeWords = 1024;// maximum size of 1024 words (32Kbit);
+
const TInt KKernelServerDefaultPriority=16;
const TInt KDefaultExitPriority=KKernelServerDefaultPriority;
@@ -2482,6 +2485,9 @@
ECodeSegRemoveAbsent=135,
EPhysicalPinObjectBad=136,
EShBufVirtualNotDefined=137, //< A required virtual method is not present in a shared buffer derived class (internal error)
+ ESecureRNGInitializationFailed = 138,
+ ESecureRNGInternalStateNotSecure = 139,
+ ESecureRNGOutputsInBadState = 140,
ESystemException=0x10000000,
ESoftwareWarmReset=0x10000001
@@ -2562,6 +2568,10 @@
static TKernelHookFn KernelHooks[ENumKernelHooks];
static TMiscNotifierMgr TheMiscNotifierMgr;
static TAny* VariantData[31];
+ static TUint32 EntropyBufferStatus[KMaxCpus];
+ static TUint32* EntropyBuffer[KMaxCpus];
+ static TUint32 TempEntropyBuffer[KEntropyBufferSizeWords];
+ static TDfc EntropyBufferDfc;
public:
static TInt InitialiseMicrokernel();
#ifdef __SMP__
@@ -2754,6 +2764,7 @@
static void Init2AP();
#endif
static void Init3();
+ static void Init4();
static TInt InitSvHeapChunk(DChunk* aChunk, TInt aSize);
static TInt InitSvStackChunk();
static TBool IsRomAddress(const TAny* aPtr);
--- a/kernel/eka/include/kernel/kern_test.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/kern_test.h Sun Mar 14 13:15:32 2010 +0000
@@ -34,7 +34,8 @@
enum TTestFunction
{
EUserModeCallbackSleep,
- EUserModeCallbackSpin,
+ EUserModeCallbackSpin,
+ ERNGReseedHook,
};
IMPORT_C static TInt Test(TTestFunction aFunc, TAny* a1 = NULL, TAny* a2 = NULL, TAny* a3 = NULL);
--- a/kernel/eka/include/kernel/kernboot.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/kernboot.h Sun Mar 14 13:15:32 2010 +0000
@@ -91,7 +91,8 @@
TUint32 iAPBootPageLin; /**< @internalComponent */
TUint32 iAPBootPageDirPhys; /**< @internalComponent */
TUint32 iSmrData; /**< address of shadow memory region information block (SMRIB), optional field set by bootstrap PSL */
- TInt iReserved[26]; /**< reserved for the future use*/
+ TUint32 iPlatformSpecificMappings;
+ TInt iReserved[25]; /**< reserved for the future use*/
};
--- a/kernel/eka/include/kernel/kernel.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/kernel.h Sun Mar 14 13:15:32 2010 +0000
@@ -250,6 +250,8 @@
const TUint8 KMutexOrdHandle = 0x30; /**< @internalComponent */
const TUint8 KMutexOrdObjectCon = 0x28; /**< @internalComponent */
const TUint8 KMutexOrdMachineConfig = 0x20; /**< @internalComponent */
+const TUint8 KMutexOrdEntropyPool = 0x12; /**< @internalComponent */
+const TUint8 KMutexOrdRandNumGeneration = 0x11; /**< @internalComponent */
const TUint8 KMutexOrdHwChunk = 0x10; /**< @internalComponent */
const TUint8 KMutexOrdKernelHeap = 0x08; /**< @internalComponent */
const TUint8 KMutexOrdRamAlloc = 0x04; /**< @internalComponent */
@@ -1011,7 +1013,11 @@
IMPORT_C static TSuperPage& SuperPage();
IMPORT_C static TMachineConfig& MachineConfig();
IMPORT_C static TUint32 Random();
- IMPORT_C static void RandomSalt(TUint32 aBit);
+ IMPORT_C static void RandomSalt(TUint32 aEntropyData);
+ IMPORT_C static void RandomSalt(TUint32 aEntropyData, TUint aBitsOfEntropy);
+ IMPORT_C static void RandomSalt(TUint64 aEntropyData, TUint aBitsOfEntropy);
+ IMPORT_C static void RandomSalt(const TUint8* aEntropyData, TUint aEntropyDataLength, TUint aBitsOfEntropy);
+ IMPORT_C static TInt SecureRandom(TDes8& aRandomValue);
IMPORT_C static void WaitForRequest(TRequestStatus& aStatus); /**< @internalTechnology */
IMPORT_C static TAny* Alloc(TInt aSize);
IMPORT_C static TAny* AllocZ(TInt aSize);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/securerng.h Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,120 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+//
+// Description:
+// eka\include\kernel\securerng.h
+//
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef __SECURERNG_H__
+#define __SECURERNG_H__
+
+#include <kernel/kern_priv.h>
+#include <assp.h>
+#include "sha256.h"
+
+//Constants required for Secure RNG
+
+// Specifies the maximum number of random requests that can be served with a single secure internal state or seed.
+// NIST recommends this value to be significantly less than 2^48 for all practical usage. The factors affecting the chosen value are
+// 1> This value should not be too high as it may weaken the strength of the random numbers generated after certain requests.
+// 2> Should be able to expose if any problems in the entropy Accumulation and Reseed unit at the earliest.
+// 3> Also depends on the number of entropy sources contributing the entropy data.
+const TUint32 KReseedInterval = 16777216; //is equal to 2^24
+// 8 (for 01) + 440 (for V) + 256 (for the hashed entropy input) + 64 (for personilazation string) => 768 / 8 = 96.
+const TUint KMaxSeedMaterialLength = 96;
+// Entropy pool threshold for reseed = HASH_DRBG security strength(256)
+const TUint KReseedThreshold = 256;
+// Entropy pool threshold for instantiation = HASH_DRBG security strength(256) + 1/2 of HASH_DRBG security strength(128) => 384
+const TUint KInstantiationThreshold = 384;
+// Maximum number of random bytes that can be served by Secure RNG. Should be less than or equal to 2^19 = 524288 bits as per HASH_DRBG algorithm
+const TInt KMaxNoOfRequestedBytes = 65536; // in bytes
+
+// SeedLength for Hash_DRBG is fixed to be 55 bytes as per Hash_DRBG Algorithm.
+const TInt KSeedLength = 55;
+
+// SHA256 hash size in bytes
+const TInt KSHA256OutLengthInBytes = 32;
+
+/**
+ *Utility functions for generating secure random numbers.
+*/
+class DSecureRNG: public DBase
+ {
+public:
+ DSecureRNG();
+
+ //Generates the requested number of random bits
+ TInt GenerateRandomNumber(TDes8& aRandomValue);
+ void AddEntropy(const TUint8* aEntropy, TInt aLength, TInt aEstimation);
+ inline TBool SecureRNGIdle() {return iSecureRNGIdle;}
+ void SetReseedHook(void (*aHookFn)(TAny*), TAny* aHookArg);
+
+private:
+ void HashGen(TDes8& aRandomValue);
+ void Reseed(const TDesC8& aEntropyInput);
+ void AddBigNumberToInternalStateV(const TUint8* aInteger2, TInt aLength);
+ void HashDf(const TDesC8& aInputData, TUint8* aOutputData);
+
+ inline void IncrementData(TDes8& aData);
+ inline TUint32 ConvertToBigEndian(TUint32 aTempCounter);
+ inline const TUint8* HashDataAndCompare(TDes8& aData);
+
+private:
+ // Mutex to enforce concurrency control over the system internal states and other related members
+ DMutex* iSecureRNGMutex;
+
+ // Mutex to enforce concurrency control over the entropy pool and entropy estimation
+ DMutex* iEntropyMutex;
+
+ SHA256 iSha256;
+
+ // Object acts as a entropy pool to hold the entropy inputs in hash context.
+ SHA256 iEntropyPool;
+
+ // Internal_State_V and Internal_State_C are secret values of Hash DRBG mechanism
+ TUint8 iInternalStateV[KSeedLength];
+ TUint8 iInternalStateC[KSeedLength];
+
+ // Required for comparision during continous random number generation test
+ TBuf8<KSHA256OutLengthInBytes> iCompareBuffer;
+
+ // Counts how many random requests are served since last reseed.
+ TUint32 iReseedCounter;
+
+ // Cumulative estimation of the so far collected entropy inputs in the pool.
+ TUint32 iEntropyEstimation;
+
+ // Holds system's current operational status (Idle / Active).
+ volatile TBool iSecureRNGIdle;
+
+ // Says whether the system is secure or not at the moment.
+ TBool iRNGSecure;
+
+ // Estimation threshold limit, decides the reseed invocation point.
+ TUint32 iEntropyThreshold;
+
+ // Hook to call on reseed
+ void (*iReseedHookFn)(TAny*);
+ TAny* iReseedHookArg;
+ };
+
+// The secure random number generator - global object.
+extern DSecureRNG *SecureRNG;
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/sha256.h Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,63 @@
+/**
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL " http://www.eclipse.org/legal/epl-v10.html ".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* kernel/eka/include
+*
+*/
+/**
+ @file
+ @internalTechnology
+ */
+
+#ifndef __SHA256_H__
+#define __SHA256_H__
+
+#include <e32cmn.h>
+#include <e32des8.h>
+#include <e32def.h>
+
+
+const TUint KSHA256BlockSize = 64;
+const TInt KSHA256HashSize = 32;
+
+class SHA256
+ {
+public:
+ SHA256(); // constructor
+ void Reset();
+ const TDesC8& Final(void);
+ void Update(const TUint8* aData,TUint aLength);
+
+private:
+ inline void AddLength(const TUint aLength);
+ inline void CopyWordToHash(TUint aVal, TInt aIndex);
+ void Block();
+ void PadMessage();
+
+private:
+ TBuf8<KSHA256HashSize> iHash;
+ TUint iA;
+ TUint iB;
+ TUint iC;
+ TUint iD;
+ TUint iE;
+ TUint iF;
+ TUint iG;
+ TUint iH;
+ TUint iData[KSHA256BlockSize];
+ TUint iNl;
+ TUint64 iNh;
+ };
+
+#endif
--- a/kernel/eka/include/kernel/x86/assp.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/kernel/x86/assp.h Sun Mar 14 13:15:32 2010 +0000
@@ -40,9 +40,10 @@
A class that exports interrupt functionality to device drivers and
other kernel-side code.
-Although Symbian OS defines this class, it does not implement it;
-an implementation for each of the functions defined by this class must
-be provided by the Variant in the baseport.
+Although Symbian OS defines this class, it does not implement the majority
+of it; an implementation for each of the functions defined by this class,
+with the exception of AddTimingEntropy, must be provided by the Variant in
+the baseport.
Note that the class only provides the public API for using interrupts,
not for dispatching them.
@@ -145,6 +146,16 @@
are not supported.
*/
IMPORT_C static TInt SetPriority(TInt anId, TInt aPriority);
+
+ /**
+ This function is implemented by the kernel. It adds the current, highest
+ resolution timestamp to the secure RNG's entropy pool.
+
+ It should be called from the ISR of any device where the timing of interrupts
+ would be considered random, for example the keyboard or digitiser drivers.
+ */
+
+ IMPORT_C static void AddTimingEntropy();
};
struct SInterruptHandler
--- a/kernel/eka/include/ws_std.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/include/ws_std.h Sun Mar 14 13:15:32 2010 +0000
@@ -79,6 +79,7 @@
{
TKeyData iKeyData;
TInt iType;
+ TUint8 iPointerNumber;
TPoint iMousePos;
TSglQueLink iLink;
};
--- a/kernel/eka/kernel/arm/bootmain.s Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/arm/bootmain.s Sun Mar 14 13:15:32 2010 +0000
@@ -1299,7 +1299,16 @@
ENDIF ; CFG_MMUPresent
ENDIF ; CFG_DebugBootRom
-
+ IF :LNOT: CFG_MemoryTypeRemapping
+ ; Pass BPR_Platform_Specific_Mappings to Kernel on platforms
+ ; with no memory type remapping feature. Kernel will emulate them
+ ; in order to support TMemoryType values 4-7
+ MOV r0, #BPR_Platform_Specific_Mappings
+ BOOTCALL BTF_Params ; r0 = BPR_Platform_Specific_Mappings
+ MOVMI r0, #0 ; r0 = 0, if parameter not defined in table.
+ STR r0, [r10, #SSuperPageBase_iPlatformSpecificMappings]
+ ENDIF
+
IF :DEF: CFG_HasL210Cache
;Enable L2 cache. Enabling L220 & PL310 is baseport specific due to security extension (TrustZone).
LDR r0, [r10, #SSuperPageBase_iArmL2CacheBase]
--- a/kernel/eka/kernel/arm/cache_external.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/arm/cache_external.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -136,9 +136,14 @@
* different master ports.
* Status:
* Not fixed in Kernel as there is no software workaround for this erratum.
+ *
+ * - 727915: Background Clean & Invalidate by Way operation can cause data corruption
+ * Status:
+ * There was no need to fix anything as PL310 cache maintenance doesn't use any
+ * _Maintain_ByWay operation. (It is only used in ExternalCache::AtomicSync on
+ * L210 & L220.)
*/
-
#include <arm.h>
#include "cache_maintenance.h"
#include <nkern.h>
@@ -314,6 +319,7 @@
#if defined(__ARM_PL310_CACHE__)
// On Pl310, we hold the lock while maintaining cache. Therefore, we cannot
// do that on a way basis as it takes too long to complete.
+ // This will also ensure that PL310 erratum 727915 is sorted out.
#if defined(__ARM_PL310_ERRATUM_588369_FIXED)
Maintain_All((TInt*)(Base+ARML2C_CleanInvalidateByIndexWay));
--- a/kernel/eka/kernel/arm/cache_maintenance.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/arm/cache_maintenance.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -31,6 +31,12 @@
TInt InternalCache::DmaBufferAlignementLog2;
#endif
+#if !defined(__CPU_MEMORY_TYPE_REMAPPING)
+TUint32 InternalCache::iPrimaryRegionRemapRegister;
+TUint32 InternalCache::iNormalMemoryRemapRegister;
+#endif
+
+
void CacheMaintenance::Init1()
{
InternalCache::Init1();
@@ -826,8 +832,27 @@
__KTRACE_OPT(KBOOT,Kern::Printf("DCache:\n"));
DumpCacheInfo(Info[KCacheInfoD]);
#endif
+#if !defined(__CPU_MEMORY_TYPE_REMAPPING)
+ // Simulate PRRR & NRRR MMU registers on platforms without memory remap feature.
+ // "Magic" numbers come from the description of ARM core's remap registers.
+ TUint32 platformSpecificMappings = TheSuperPage().iPlatformSpecificMappings;
+ iPrimaryRegionRemapRegister = KDefaultPrimaryRegionRemapRegister | ((platformSpecificMappings&0x3f)<<10);
+ iNormalMemoryRemapRegister = KDefaultNormalMemoryRemapRegister | (platformSpecificMappings&0xfc00fc00);
+#endif //!defined(__CPU_MEMORY_TYPE_REMAPPING)
}
+#if !defined(__CPU_MEMORY_TYPE_REMAPPING)
+TUint32 InternalCache::PrimaryRegionRemapRegister()
+ {
+ return iPrimaryRegionRemapRegister;
+ }
+
+TUint32 InternalCache::NormalMemoryRemapRegister()
+ {
+ return iNormalMemoryRemapRegister;
+ }
+#endif //!defined(__CPU_MEMORY_TYPE_REMAPPING)
+
#endif //else defined(__CPU_ARMV7)
#ifdef __BROADCAST_CACHE_MAINTENANCE__
@@ -995,8 +1020,7 @@
TUint32 InternalCache::TypeToCachingAttributes(TMemoryType aType)
- {
-
+ {
TUint32 attr = 0;
switch (aType)
{
@@ -1010,7 +1034,6 @@
case EMemAttPlatformSpecific6:
case EMemAttPlatformSpecific7:
{
- #if defined(__CPU_MEMORY_TYPE_REMAPPING)
// The mapping of these types are defined in bootstrap.
// Read remap registers and set mapping attributes accordingly.
// "Magic" numbers come from the description of ARM core's remap registers.
@@ -1044,9 +1067,6 @@
default:
CACHEFAULT(); //unsupported value (3) in Primary Region Remap Register
}
- #else //defined(__CPU_MEMORY_TYPE_REMAPPING)
- CACHEFAULT(); // memory types 4-7 are not supported on these platforms
- #endif
}
break;
default:
--- a/kernel/eka/kernel/ekern.mmp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/ekern.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -139,6 +139,7 @@
source sexec.cpp sinit.cpp skernel.cpp
source scodeseg.cpp sipc.cpp notifier.cpp
source object.cpp power.cpp server.cpp
+source sha256.cpp securerng.cpp
source stimer.cpp sutils.cpp random.cpp
source sprocess.cpp sthread.cpp
source smqueue.cpp
@@ -150,6 +151,7 @@
source sbtrace.cpp
source stest.cpp
source sshbuf.cpp smap.cpp
+source srandombuff.cpp
sourcepath ../klib
source dbase.cpp kdes8.cpp
--- a/kernel/eka/kernel/execs.txt Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/execs.txt Sun Mar 14 13:15:32 2010 +0000
@@ -640,7 +640,6 @@
name = MathRandom
return = TUint32
kernel = Kern::Random
- lock
}
slow {
@@ -2431,6 +2430,14 @@
norelease
}
+
+slow {
+ name = MathSecureRandom
+ return = TInt
+ arg1 = TDes8&
+}
+
+
/******************************************************************************
* End of normal executive functions
******************************************************************************/
@@ -2461,3 +2468,4 @@
return = TInt
}
+
--- a/kernel/eka/kernel/random.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/random.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -16,52 +16,23 @@
//
#include <kernel/kern_priv.h>
-
-//
-// Generate nth random number using the following algorithm
-//
-// X[n] = ((X[n-j] rotl r1) + (X[n-k] rotl r2)) modulo 2^b
-//
-// k=17, j=10, r1=5, r2=3
-//
-
-const TInt KBufferSize=17;
-const TInt KBufferSizeInBits=KBufferSize*32;
-const TInt KPointer2Offset=10; // Must be less than KBufferSize
-
-TUint32 RandomBuffer[KBufferSize];
-TInt RandomPointer=1;
-TInt RandomSaltPointer=KBufferSizeInBits-1;
-
-inline TUint32 RotateLeft5(TUint32 aVal)
- { return (aVal << 5) | (aVal >> 27); }
+#include "securerng.h"
+#include "execs.h"
-inline TUint32 RotateLeft3(TUint32 aVal)
- { return (aVal << 3) | (aVal >> 29); }
-
-void K::Randomize()
-//
-// Initialise the random pool
-//
- {
- TUint64 seed=K::TickQ->iRtc;
- TInt i;
- for (i=0; i<KBufferSize; i++)
- {
- RandomBuffer[i] = TUint32(seed);
- seed= ((seed<<5) + (seed>>59)) + 97;
- }
- NKern::LockSystem();
- for (i=0; i<50; i++)
- Kern::Random();
- NKern::UnlockSystem();
- }
-
+// The global pointer to the RNG instance
+DSecureRNG* SecureRNG;
/**
- Generate the next random number.
+ Gets 32 random bits from the kernel's random number generator.
+
+ The returned random data may or may not be cryptographically secure but should be of a high quality for
+ non-cryptographic purposes.
- @return The generated random number.
+ This function uses a cryptographically strong random number generator to generate the random data, which can
+ be slower than insecure generators. If security is not important, you may wish to use a trivial RNG instead
+ for performance.
+
+ @return The 32 random bits.
@pre Kernel Lock must not be held.
@pre No fast mutex should be held
@@ -70,42 +41,116 @@
*/
EXPORT_C TUint32 Kern::Random()
{
- TBool alreadyLocked = TheScheduler.iLock.HeldByCurrentThread();
- if (!alreadyLocked)
- NKern::LockSystem();
- TInt p1 = RandomPointer;
- if(--p1<0)
- p1 = KBufferSize-1;
- RandomPointer = p1;
- TInt p2 = p1+KPointer2Offset;
- if(p2>KBufferSize-1)
- p2 -= KBufferSize-1;
- TUint32 r = RandomBuffer[p1] = RotateLeft5(RandomBuffer[p2])+RotateLeft3(RandomBuffer[p1]);
- if (!alreadyLocked)
- NKern::UnlockSystem();
- return r;
+ CHECK_PRECONDITIONS(MASK_THREAD_STANDARD, "Kern::Random()");
+ TBuf8<4> randomBuffer;
+ randomBuffer.SetMax();
+ SecureRNG->GenerateRandomNumber(randomBuffer);
+ return *((const TUint32*)randomBuffer.Ptr());
+ }
+
+/**
+ Fills the provided descriptor with random data up to its current length. The number of random bytes required
+ should be specified by setting the length of the descriptor that is passed to the function.
+
+ If the returned random data cannot be guaranteed to be cryptographically secure, the function will return
+ KErrNotReady, but data will still be provided suitable for non-cryptographic purposes.
+
+ The security strength of the cryptograpically strong random number generator is 256 bits.
+
+ @param aRandomValue on return, the descriptor is filled with the requested number of random bytes.
+
+ @return KErrArgument if more than 65536 bytes are requested in a single call.
+ KErrNotReady if the returned random data cannot be guaranteed to be cryptographically secure.
+ KErrNone if the returned random data is believed to be cryptographically secure.
+
+ @pre Kernel Lock must not be held
+ @pre No fast mutex should be held
+ @pre Interrupts should be enabled
+ @pre Can be used in a device driver.
+*/
+EXPORT_C TInt Kern::SecureRandom(TDes8& aRandomValue)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_STANDARD, "Kern::SecureRandom(TDes8&)");
+ return SecureRNG->GenerateRandomNumber(aRandomValue);
}
/**
- Adds a bit to the random pool used to generate random numbers.
- This method should be used by any sources of entropy to improve the quality of
- random number generation.
+ Adds the given entropy input to the entropy pool used for random number generation.
+ This is the only version of Kern::RandomSalt which allows entropy samples larger than 8 bytes to be added.
+
+ Entropy estimates should be chosen carefully to reflect the minimum entropy that the sample may contain.
- @param aBitOfSalt The least significant bit of this value is added to the random pool.
+ @param aEntropyData Pointer to the entropy data.
+ @param aEntropyDataLength Length of the entropy data in bytes.
+ @param aBitsOfEntropy The amount of entropy (in bits) present in the entropy data.
- @pre Can be used in a device driver.
+ @pre Kernel Lock must not be held
+ @pre No fast mutex should be held
+ @pre Interrupts should be enabled
+ @pre Can be used in a device driver.
*/
-EXPORT_C void Kern::RandomSalt(TUint32 aBitOfSalt)
+EXPORT_C void Kern::RandomSalt(const TUint8* aEntropyData, TUint aEntropyDataLength, TUint aBitsOfEntropy)
{
- TInt p=RandomSaltPointer; // protect RandomSaltPointer from re-entrantrancy
- if (aBitOfSalt&=1)
+ CHECK_PRECONDITIONS(MASK_THREAD_STANDARD, "Kern::RandomSalt(const TUint8*, TUint, TUint)");
+
+ // Check if the claimed entropy estimation (in bits) is not more than the maximum value.
+ __ASSERT_ALWAYS(aBitsOfEntropy <= aEntropyDataLength*8, K::PanicKernExec(EEntropyEstimateOutOfRange));
+
+ // If the Secure RNG system is not in idle mode, add the collected entropy to the entropy pool.
+ if (!SecureRNG->SecureRNGIdle())
{
- TInt word=p >> 5;
- TInt bit=p & 0x1f;
- RandomBuffer[word] ^= aBitOfSalt << bit;
+ SecureRNG->AddEntropy(aEntropyData, aEntropyDataLength, aBitsOfEntropy);
}
- if (--p<0)
- p=KBufferSizeInBits-1;
- RandomSaltPointer=p;
}
+/*
+ * Exec handler function for obtaining secure random numbers
+ */
+TInt ExecHandler::MathSecureRandom(TDes8& aRandomValue)
+ {
+ TInt randomValueLength = 0;
+ TInt randomValueMaxLength = 0;
+ //Gets information about the user specified descriptor.
+ TUint8* kernelPtr = (TUint8*)Kern::KUDesInfo(aRandomValue, randomValueLength, randomValueMaxLength);
+ if(randomValueMaxLength == -1) //user passed descriptor is not writable
+ {
+ K::PanicKernExec(EKUDesSetLengthInvalidType);
+ }
+
+ // The random number generator requires a temporary buffer to write the data to, before we write it back to
+ // userspace's buffer. The buffer is allocated here on the stack to avoid having to heap-allocate, and if
+ // the requested amount of data is larger, a loop is used. 2048 bytes will always fit onto the stack in an
+ // exec handler.
+ const TInt KRandomBufferSize = 2048;
+ TBuf8<KRandomBufferSize> randomBuffer;
+
+ TInt err = KErrNone;
+ TBool isKErrNotReadyTrue = EFalse;
+ while(randomValueLength > 0)
+ {
+ TInt noOfBytesToGenerate = (randomValueLength > KRandomBufferSize) ? KRandomBufferSize : randomValueLength;
+ randomBuffer.SetLength(noOfBytesToGenerate);
+ // Generate random numbers
+ err = Kern::SecureRandom(randomBuffer);
+ if(err == KErrNotReady)
+ {
+ isKErrNotReadyTrue = ETrue;
+ }
+ else if (err != KErrNone)
+ {
+ return err; // any other system wide error code needs to be returned immediately.
+ }
+ // Copy the generated random numbers to the user descriptor.
+ umemput(kernelPtr, randomBuffer.Ptr(), noOfBytesToGenerate);
+ kernelPtr += KRandomBufferSize;
+ randomValueLength -= KRandomBufferSize;
+ }
+
+ // Atleast one KErrNotReady error was generated during processing the request, so return the state as not ready
+ // indicating the internal states was not secure during random number generation.
+ if(isKErrNotReadyTrue)
+ {
+ return KErrNotReady;
+ }
+ return err;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/securerng.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,387 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// eka\kernel\securerng.cpp
+//
+//
+
+#include "kernel/securerng.h"
+#include "sha256.h"
+
+/**
+ * Default Constructor.
+ * Initialize the Secure RNG with values for iInternalStateV, iInternalStateC, Reseed_Counter
+ * Entropy Pool threshold and Secure RNG status
+ */
+DSecureRNG::DSecureRNG() :
+ iSha256(),
+ iEntropyPool(),
+ iReseedCounter(0),
+ iEntropyEstimation(0),
+ iSecureRNGIdle(EFalse),
+ iRNGSecure(EFalse),
+ iEntropyThreshold(KInstantiationThreshold)
+ {
+ // Create the Mutex objects before initializing the internal state.
+ _LIT(KRNGMutexName,"SecureRNGMutex");
+ _LIT(KEntropyMutexName,"EntropyMutex");
+ NKern::ThreadEnterCS();
+ __ASSERT_ALWAYS(Kern::MutexCreate(iSecureRNGMutex, KRNGMutexName, KMutexOrdRandNumGeneration) == KErrNone,
+ K::Fault(K::ESecureRNGInitializationFailed));
+ __ASSERT_ALWAYS(Kern::MutexCreate(iEntropyMutex, KEntropyMutexName, KMutexOrdEntropyPool) == KErrNone,
+ K::Fault(K::ESecureRNGInitializationFailed));
+ NKern::ThreadLeaveCS();
+
+ // Initially feed the internal state with the current system time tick
+ TUint64 tick = Kern::SystemTimeSecure();
+ TBuf8<sizeof(TUint64)> entropyInput;
+ entropyInput.Copy((TUint8*)(&tick), sizeof(TUint64));
+
+ // Initialize the system internal state with the time tick as entropy input.
+ Reseed(entropyInput);
+ }
+
+/**
+ * Random Number Generation Algorithm:
+ * 1.If reseed_counter > reseed_interval, then return an indication that a reseed is required.
+ * 2.(returned_bits) = Hashgen (requested_number_of_bits, V).
+ * 3. H = Hash (0x03 || V). Where 0x03 is represented in one byte
+ * 4. V = (V + H + C + reseed_counter) mod 2 ^seedlen.
+ * 5. reseed_counter = reseed_counter + 1.
+ * 6. Return SUCCESS, and update the new values of V, C, and reseed_counter
+ * for the new_working_state.
+ * @param aRandomValue on return will contain the generated random numbers.The length of random number
+ * generated will be equal to the current length of the descriptor(aRandomValue)
+ * passed as argument to the function call
+ @panic Panics the kernel with KErrNotReady when the number of requests that can be served has crossed it maximum limit
+ of KReseedInterval. The panic will indicate that something has badly gone wrong with the Entropy accumulation and
+ Reseed unit.
+ * @return KErrNone if everything is fine or KErrNotReady when the system is not ready yet.
+ */
+TInt DSecureRNG::GenerateRandomNumber(TDes8& aRandomValue)
+ {
+ // If requested for random numbers greater than the max limit specified by HASH_DRBG (2^19 bits = 65536 bytes), return error
+ if(aRandomValue.Length() > KMaxNoOfRequestedBytes)
+ {
+ return KErrArgument;
+ }
+
+ // Secure the random number generation operation through mutex
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iSecureRNGMutex);
+ if(iReseedCounter >= KReseedInterval && iRNGSecure)
+ {
+ // If we got reseeded before but haven't been reseeded inside the interval, then something must
+ // have happened to the entropy collection mechanism (the interval is quite large) - possibly we
+ // are under attack. There is no way to return to a secure state, so fault the system.
+ K::Fault(K::ESecureRNGInternalStateNotSecure);
+ }
+ iSecureRNGIdle = EFalse;
+
+ // Generate the random numbers
+ HashGen(aRandomValue);
+
+ const TUint8 KRngConstant = 0x03;
+ iSha256.Update((TUint8*)&KRngConstant, sizeof(TUint8));
+ iSha256.Update(iInternalStateV , KSeedLength);
+
+ // Update the secret value of the Internal State V so that back tracking can be avoided.
+ // V = (V+C+H+reseed_counter) mod 2 ^seedlength
+ AddBigNumberToInternalStateV(iInternalStateC, KSeedLength);
+ AddBigNumberToInternalStateV(iSha256.Final().Ptr(),KSHA256OutLengthInBytes );
+
+ // Converts iReseedCounter value from little endian to big endian format and stores in tempcounter.
+ TUint32 tempCounter = ConvertToBigEndian(iReseedCounter);
+ AddBigNumberToInternalStateV((TUint8*)&tempCounter,sizeof(tempCounter));
+
+ ++iReseedCounter;
+ TBool rngSecure = iRNGSecure;
+ Kern::MutexSignal(*iSecureRNGMutex);
+ NKern::ThreadLeaveCS();
+
+ if(rngSecure)
+ {
+ return KErrNone;
+ }
+ return KErrNotReady;
+ }
+
+/**
+ * Converts the aTempCounter from little endian format to big endian format. This conversion is required
+ * for performing addition in the function AddBigNumbers().
+ * Works fine for 32 bits data only.
+ * @ return TUint32, big endian format 32 bit value of the iReseedCounter
+ */
+inline TUint32 DSecureRNG::ConvertToBigEndian(TUint32 aTempCounter)
+ {
+ return ((aTempCounter >> 24 & 0x000000ff)| (aTempCounter<< 8 & 0x00ff0000)
+ |(aTempCounter>>8 & 0x0000ff00) | (aTempCounter << 24 &0xff000000));
+ }
+
+/**
+ * This function performs addition of an integer(aInteger) passed to the function with iInternalStateV and
+ * the result is stored in iInternalStateV. The function is required to update the internal state of
+ * V(iInternalStateV) after each random number generation request.
+ * @param aInteger this is the input paramenter which is added with iInternalStateV and the result
+ * is stored in iInternalStateV
+ * @param aLength length of the aInteger( integer that needs to be added to iInternalStateV) passed to the function
+ */
+void DSecureRNG::AddBigNumberToInternalStateV(const TUint8* aInteger, TInt aLength)
+ {
+ TUint8 sum[2]= {0};
+ TInt index = KSeedLength;
+ while(--index >= 0 && (--aLength >= 0 || sum[1] == 1))
+ {
+ TUint8 integer = (aLength >= 0) ? aInteger[aLength] : (TUint8)0 ;
+ // sum[0]will hold the value of addition operation and sum[1] will hold carry (if any)
+ *(TUint16*)&sum = TUint16(iInternalStateV[index] + integer + sum[1]);
+ iInternalStateV[index] = sum[0];
+ }
+ }
+
+/**
+ *Generate the next random number bits to be returned.
+ * HashGen Algorith:
+ * 1. m = requested_number_of_bits/ KSHA256OutLengthInBytes.
+ * 2. data = V.
+ * 3. W = the Null string.
+ * 4. For i = 1 to m
+ * 4.1 wi = Hash (data).
+ * 4.2 W = W || wi.
+ * 4.3 data = (data + 1) mod 2^seedlen.
+ * 5. returned_bits = Leftmost (requested_no_of_bits) bits of W.
+ *
+ * Continuous Random number generation test: This is FIPS recommended (FIPS 140-2)test. Definition as per FIPS:-
+ * 1. If each call to a RNG produces blocks of n bits (where n > 15), the first n-bit block generated
+ * after power-up, initialization, or reset shall not be used, but shall be saved for comparison with
+ * the next n-bit block to be generated. Each subsequent generation of an n-bit block shall be compared
+ * with the previously generated block. The test shall fail if any two compared n-bit blocks are equal.
+ * 2. If each call to a RNG produces fewer than 16 bits, the first n bits generated after power-up,
+ * initialization, or reset (for some n > 15) shall not be used, but shall be saved for comparison
+ * with the next n generated bits. Each subsequent generation of n bits shall be compared with the
+ * previously generated n bits. The test fails if any two compared n-bit sequences are equal.
+ *
+ * @param aRandomBuffer on return, the descriptor will contain the generated random bytes.
+ *
+ */
+void DSecureRNG::HashGen(TDes8& aRandomBuffer)
+ {
+ TBuf8<KSeedLength> data;
+ // data = V(iInternalStateV)
+ data.Copy(iInternalStateV, KSeedLength);
+
+ TInt noOfBytesToCopy = aRandomBuffer.Length();
+ TInt newLength = noOfBytesToCopy;
+ //set the length to zero
+ aRandomBuffer.Zero();
+ while(noOfBytesToCopy > 0)
+ {
+ newLength = noOfBytesToCopy > KSHA256OutLengthInBytes ? KSHA256OutLengthInBytes: noOfBytesToCopy;
+ // Append Hashed Data to buffer
+ aRandomBuffer.Append(HashDataAndCompare(data), newLength);
+ IncrementData(data);
+ noOfBytesToCopy = noOfBytesToCopy - KSHA256OutLengthInBytes;
+ }
+ }
+
+/*
+ * Generates Hash of the aData and compares it with previous generated n(256) random bits to verify for
+ * Continuous Random number generation test.
+ * @param aData, the latest copy of iInternalStateV value to be used hash operation
+ * @return ptr, pointer to the generated hash value using sha256
+ */
+inline const TUint8* DSecureRNG::HashDataAndCompare(TDes8& aData)
+ {
+ iSha256.Update(aData.Ptr(), aData.Length());
+ const TDesC8& ptr = iSha256.Final();
+ if(iCompareBuffer.Length()!= 0)
+ {
+ // According to FIPS 140-2: if the n-bit random number is same as the previously generated
+ // n-bit random number then fault the system
+ __ASSERT_ALWAYS(iCompareBuffer.Compare(ptr)!= 0,K::Fault(K::ESecureRNGOutputsInBadState));
+ }
+ iCompareBuffer.Copy(ptr);
+ return ptr.Ptr();
+ }
+
+/**
+ * Calculates (data+1) modulus of 2^440.
+ * @return aData, on return contains aData value incremented by one
+ */
+inline void DSecureRNG::IncrementData(TDes8& aData)
+ {
+ TInt i = KSeedLength-1;
+ aData[i] += 1;
+ while( i > 0 && aData[i] == 0)
+ {
+ aData[--i] +=1;
+ }
+ }
+
+/**
+ * The hash-based derivation function hashes the given input string and
+ * returns the required no. of bits of hash value on the second parameter.
+ * Algorithm:
+ * 1. temp = the Null string.
+ * 2. len = no_of_bits_to_return / out_len.
+ * 3. counter = an 8-bit binary value representing the integer "1".
+ * 4. For i = 1 to len do //Comment : In step 4.1, no_of_bits_to_return is used as a 32-bit string.
+ * 4.1 temp = temp || Hash (counter || no_of_bits_to_return || input_string).
+ * 4.2 counter = counter + 1.
+ * 5. requested_bits = Leftmost (no_of_bits_to_return) of temp.
+ * 6. Return SUCCESS and requested_bits.
+ *
+ * In our case, the no_of_bits_to_return and out_len are constants 440, 256 respectively
+ * and hence the KLoopLength too becomes constant 2.
+ * @param, aInputData, holds the input data(state) which needs to be updated
+ * @param aOutputData, on return will have the updated value of internal State
+*/
+void DSecureRNG::HashDf(const TDesC8& aInputData, TUint8* aOutputData)
+ {
+ // Seed Length is 440 and SHA256 output block length 256. So required iterations is 2 for 440 bits
+ const TUint8 KLoopLength = 2;
+ const TUint32 KNumOfBitsToReturn = KSeedLength * 8;
+ TInt length = KSHA256OutLengthInBytes;
+ // Note: The 'length' in memcpy works fine only for curent seed length (440 bits => two iterations)
+ // In future, if the seed length changes, this too should be modified accoringly.
+ for (TUint8 counter = 1; counter<= KLoopLength; ++counter)
+ {
+ iSha256.Update(&counter, sizeof(TUint8));
+ iSha256.Update((TUint8*)&KNumOfBitsToReturn, sizeof(TUint32));
+ iSha256.Update(aInputData.Ptr(), aInputData.Length());
+ memmove((aOutputData + (counter-1) * KSHA256OutLengthInBytes), iSha256.Final().Ptr(), length);
+ length = KSeedLength - KSHA256OutLengthInBytes;
+ }
+ }
+
+ /**
+ * This method would generate the new seed with the entropy passed in and update the internal state
+ * based on the new seed generated. Seed Generation should happen in the following two cases.
+ * Instantiattion: Internal state updation for the first time with sufficient entropy.
+ * 1. construct the seed material : seed_material = entropy_input
+ * 2. seed = Hash_df (seed_material, seedlen).
+ * 3. V = seed.
+ * 4. C = Hash_df ((0x00 || V), seedlen). // Precede with a byte of all zeros.
+ * 5. reseed_counter = 0.
+ *
+ * Reseeding: Internal state updation with the sufficient entropy for all instances except first time.
+ * 1. construct the seed material : seed_material = 0x01 || V || entropy_input
+ * 2. seed = Hash_df (seed_material, seedlen).
+ * 3. V = seed.
+ * 4. C = Hash_df ((0x00 || V), seedlen). // Precede with a byte of all zeros.
+ * 5. reseed_counter = 0.
+ *
+ * In both the cases only the step 1 differs. All other steps are common for both.
+ * The internal state and other relevant members are protected by the mutex.
+ * @param aEntropyInput, holds the entropy input values required to update the internal states
+*/
+void DSecureRNG::Reseed(const TDesC8& aEntropyInput)
+ {
+ const TUint8 KConstOne = 0x01;
+ TBuf8<KMaxSeedMaterialLength> seedMaterial;
+
+ // Construct the seed material.
+ if(iRNGSecure)
+ {
+ // After the first seeding (which will set iRNGSecure), seed_material = 0x01 || V || entropy_input
+ seedMaterial.Append(&KConstOne, sizeof(TUint8));
+ seedMaterial.Append(iInternalStateV, KSeedLength);
+
+ // Make the system idle on every reseed (will be reset next time the RNG is used)
+ iSecureRNGIdle = ETrue;
+ }
+
+ // The enropy input is used whether it's the first seeding or not.
+ seedMaterial.Append(aEntropyInput);
+
+ // On the first seeding, include the personalizsation string for the instantiation.
+ if(!iRNGSecure)
+ {
+ // System time in ticks is considered as a personalization string
+ TInt64 personalizationString = Kern::SystemTimeSecure();
+ seedMaterial.Append((TUint8*)&personalizationString, sizeof(TUint));
+ }
+
+ // Calculate the seed and update the internal state V
+ HashDf(seedMaterial, iInternalStateV);
+
+ // Calculate and update the internal state C
+ seedMaterial.FillZ(1); // Put the 0x00 in the first byte of the buffer
+ seedMaterial.Append(iInternalStateV, KSeedLength);
+ HashDf(seedMaterial, iInternalStateC);
+
+ // Reset the reseed counter and other related parameter values as well.
+ iReseedCounter = 0;
+ iEntropyPool.Reset();
+ // Reset the current estimation.
+ iEntropyEstimation = 0;
+ }
+
+/**
+ * Controls the Reseed process with the following algorithm.
+ * 1. Collect the received entropy in the entropy pool like hash object.
+ * 2. Increment the entropy estimation counter by the received estimation value.
+ * 3. If the so far collected estimation is higher than the threshold value,
+ * 3.1. Call Reseed to generate the new seed and update the system internal state
+ * 3.2. Decide the secure status of the new seed and hence the RNG system
+ * 3.3. Decide whether the system is idle or not
+ * 3.4. Reset the entropy pool hash object and the entropy estimation counter.
+ *
+*/
+void DSecureRNG::AddEntropy(const TUint8* aEntropy, TInt aLength, TInt aEstimation)
+ {
+ // Get the mutex to update the entropy pool
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iEntropyMutex);
+
+ iEntropyPool.Update(aEntropy, aLength);
+ iEntropyEstimation += aEstimation;
+
+ if (iEntropyEstimation >= iEntropyThreshold)
+ {
+ // Get the mutex to update the internal state via Reseed.
+ Kern::MutexWait(*iSecureRNGMutex);
+
+ // Get the final hash value and pass on to the reseed, which inturn will update the internal state.
+ Reseed(iEntropyPool.Final());
+
+ // Set the threshold to 256 for all but the first reseed. For instantiation
+ // the threshold should be 384 which was set already as part of initialization.
+ iEntropyThreshold = KReseedThreshold;
+
+ // As the entropy estimation has crossed the threshold, the system becomes secure.
+ iRNGSecure = ETrue;
+
+ // Send the reseed notification to the hook, if one is installed
+ if (iReseedHookFn)
+ iReseedHookFn(iReseedHookArg);
+
+ // Updates are done. So, release the Mutex.
+ Kern::MutexSignal(*iSecureRNGMutex);
+ }
+
+ // Updates are done. So, release the Mutex.
+ Kern::MutexSignal(*iEntropyMutex);
+ NKern::ThreadLeaveCS();
+ }
+
+// Allow a test driver to set a hook function which will be called on reseed.
+void DSecureRNG::SetReseedHook(void (*aReseedHookFn)(TAny*), TAny* aReseedHookArg)
+ {
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iSecureRNGMutex);
+ iReseedHookFn = aReseedHookFn;
+ iReseedHookArg = aReseedHookArg;
+ Kern::MutexSignal(*iSecureRNGMutex);
+ NKern::ThreadLeaveCS();
+ }
--- a/kernel/eka/kernel/sglobals.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/sglobals.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -22,6 +22,8 @@
TLinAddr SuperPageAddress;
}
+extern void DrainEntropyBuffers(TAny*);
+
TMachineConfig* K::MachineConfig;
RAllocator* K::Allocator;
K::SHeapInfo K::HeapInfo;
@@ -116,4 +118,18 @@
TMiscNotifierMgr K::TheMiscNotifierMgr;
TAny* K::VariantData[31];
+// Array of per CPU entropy buffer status values, each has the number of words used in the bottom 14 bits,
+// which may not exceed 2^13 words (32KB or 256Kbit).
+// The top 18 bits is the number of bits of entropy with maximum value 2^18 or 256Kbit which matches the buffer size.
+TUint32 K::EntropyBufferStatus[KMaxCpus];
+
+// Array of per CPU pointers to entropy buffers.
+TUint32* K::EntropyBuffer[KMaxCpus];
+
+// Temporary buffer to drain per cpu buffers to
+TUint32 K::TempEntropyBuffer[KEntropyBufferSizeWords];
+
+// DFC to drain entropy buffers
+TDfc K::EntropyBufferDfc(DrainEntropyBuffers, NULL, 1);
+
TDfcQue DShPool::iSharedDfcQue; // DFCQ thread for shareable data buffers growing/shrinking/notifications
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/sha256.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,464 @@
+/**
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL " http://www.eclipse.org/legal/epl-v10.html ".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: SHA256 implementation for Random number generation
+* kernel\sha256.cpp
+*
+*/
+
+#include "sha256.h"
+
+
+/**
+ * SHA256 Constants
+ *
+ * SHA-256 uses a sequence of sixty-four constant 32-bit words.
+ * These words represent the first thirty-two bits of the fractional
+ * parts of the cube roots of the first sixtyfour prime numbers.
+ *
+ * FIPS 180-2 Section 4.2.2
+ */
+const TUint K[64] =
+ {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+
+inline TUint SHA_Ch(TUint aX, TUint aY, TUint aZ)
+ {
+ return ((aX & aY) ^ ((~aX) & aZ));
+ }
+
+inline TUint SHA_Maj(TUint aX, TUint aY, TUint aZ)
+ {
+ return ((aX & aY) ^ (aX & aZ) ^ (aY & aZ));
+ }
+
+/**
+ * SHA Rotate Right Operation: The rotate right (circular right shift) operation
+ * ROTR^n(x), where x is a w-bit word and n is an integer with 0 <= n < w,
+ * is defined by ROTR n(x)=(x >> n) || (x << w - n).
+ */
+inline TUint SHA_ROTR(TUint aBits, TUint aWord)
+ {
+ TInt totalBits = sizeof(TUint) << 3;
+ return ((aWord >> aBits) | (aWord << (totalBits-aBits)));
+ }
+
+
+/**
+ * Define the SHA shift, and rotate right macro
+ * Defined in FIPS 180-2 Section 3.2
+ */
+/**
+ * SHA Right Shift operation: The right shift operation SHR^n(x),
+ * where x is a w-bit word and n is an integer with 0 <= n < w,
+ * is defined by SHR^n(x) = x >> n.
+ */
+inline TUint SHA_SHR(TUint aBits, TUint aWord)
+ {
+ return (aWord >> aBits);
+ }
+
+/**
+ * Define the SHA SIGMA and sigma macros
+ *
+ * FIPS 180-2 section 4.1.2
+ */
+// Equation 4.4
+inline TUint SHA256_SIGMA0(TUint aWord)
+ {
+ return (SHA_ROTR(2,aWord) ^ SHA_ROTR(13,aWord) ^ SHA_ROTR(22,aWord));
+ }
+// Equation 4.5
+inline TUint SHA256_SIGMA1(TUint aWord)
+ {
+ return (SHA_ROTR(6,aWord) ^ SHA_ROTR(11,aWord) ^ SHA_ROTR(25,aWord));
+ }
+// Equation 4.6
+inline TUint SHA256_sigma0(TUint aWord)
+ {
+ return (SHA_ROTR(7,aWord) ^ SHA_ROTR(18,aWord) ^ SHA_SHR(3,aWord));
+ }
+// Equation 4.7
+inline TUint SHA256_sigma1(TUint aWord)
+ {
+ return (SHA_ROTR(17,aWord) ^ SHA_ROTR(19,aWord) ^ SHA_SHR(10,aWord));
+ }
+
+// Macros
+inline TUint MakeWord(const TUint8* aData)
+ {
+ return (aData[0] << 24 | aData[1] << 16 | aData[2] << 8 | aData[3]);
+ }
+
+// Constructor
+SHA256::SHA256()
+ {
+ Reset();
+ }
+
+ void SHA256::Reset()
+ {
+ /**
+ * Initial Hash Value
+ *
+ * These words were obtained by taking the first thirty-two bits
+ * of the fractional parts of the square roots of the first eight
+ * prime numbers.
+ *
+ * FIPS 180-2 Section 5.3.2
+ */
+ iA=0x6a09e667;
+ iB=0xbb67ae85;
+ iC=0x3c6ef372;
+ iD=0xa54ff53a;
+ iE=0x510e527f;
+ iF=0x9b05688c;
+ iG=0x1f83d9ab;
+ iH=0x5be0cd19;
+ iNh=0;
+ iNl=0;
+ }
+
+// This assumes a big-endian architecture
+ void SHA256::Update(const TUint8* aData,TUint aLength)
+ {
+ while((aLength / 4) > 0 && (iNl % 4 == 0))
+ {
+ iData[iNl>>2] = MakeWord(aData);
+ iNl+=4;
+ aData+=4;
+ aLength-=4;
+ if(iNl==KSHA256BlockSize)
+ {
+ Block();
+ AddLength(KSHA256BlockSize);
+ }
+ }
+
+ while(aLength--)
+ {
+ if(!(iNl&0x03))
+ {
+ iData[iNl >> 2] = 0;
+ }
+ iData[iNl >> 2] |= *aData << ((3 - iNl&0x03) << 3) ;
+ ++aData;
+ ++iNl;
+ if(iNl==KSHA256BlockSize)
+ {
+ Block();
+ AddLength(KSHA256BlockSize);
+ }
+ }
+ }
+
+inline void SHA256::AddLength(const TUint aLength)
+ {
+ iNh += aLength << 3;
+ }
+
+
+static inline void CSHA256_16( const TUint aA,
+ const TUint aB,
+ const TUint aC,
+ TUint& aD,
+ const TUint aE,
+ const TUint aF,
+ const TUint aG,
+ TUint& aH,
+ TUint aTemp1,
+ TUint aTemp2,
+ const TUint aK,
+ const TUint aWord)
+ {
+ aTemp1 = aH + SHA256_SIGMA1(aE) + SHA_Ch(aE,aF,aG) + aK + aWord;
+ aTemp2 = SHA256_SIGMA0(aA) + SHA_Maj(aA,aB,aC);
+ aD = aD + aTemp1;
+ aH = aTemp1 + aTemp2;
+ }
+
+static inline void CSHA256_48( const TUint aA,
+ const TUint aB,
+ const TUint aC,
+ TUint& aD,
+ const TUint aE,
+ const TUint aF,
+ const TUint aG,
+ TUint& aH,
+ TUint aTemp1,
+ TUint aTemp2,
+ const TUint aK,
+ TUint& aWord0,
+ const TUint aWord2,
+ const TUint aWord7,
+ const TUint aWord15,
+ const TUint aWord16)
+ {
+ aWord0 = SHA256_sigma1(aWord2) + aWord7 + SHA256_sigma0(aWord15) + aWord16;
+ CSHA256_16(aA, aB, aC, aD, aE, aF, aG, aH, aTemp1, aTemp2, aK, aWord0);
+ }
+
+/**
+ * This function actually calculates the hash.
+ * Function is defined in FIPS 180-2 section 6.2.2
+ *
+ * This function is the expanded version of the following loop.
+ * for(TUint i = 0; i < 64; ++i)
+ * {
+ * if(i >= 16)
+ * {
+ * iData[i] = SHA256_sigma1(iData[i-2]) + iData[i-7] + SHA256_sigma0(iData[i-15]) + iData[i-16];
+ * }
+ *
+ * temp1 = tempH + SHA256_SIGMA1(tempE) + SHA_Ch(tempE,tempF,tempG) + K[i] + iData[i];
+ * temp2 = SHA256_SIGMA0(tempA) + SHA_Maj(tempA,tempB,tempC);
+ * tempH = tempG;
+ * tempG = tempF;
+ * tempF = tempE;
+ * tempE = tempD + temp1;
+ * tempD = tempC;
+ * tempC = tempB;
+ * tempB = tempA;
+ * tempA = temp1 + temp2;
+ * }
+ */
+void SHA256::Block()
+ {
+ TUint tempA=iA;
+ TUint tempB=iB;
+ TUint tempC=iC;
+ TUint tempD=iD;
+ TUint tempE=iE;
+ TUint tempF=iF;
+ TUint tempG=iG;
+ TUint tempH=iH;
+ TUint temp1=0;
+ TUint temp2=0;
+
+ CSHA256_16(tempA,tempB,tempC,tempD,tempE,tempF,tempG,tempH,temp1,temp2,K[0],iData[0]);
+ CSHA256_16(tempH,tempA,tempB,tempC,tempD,tempE,tempF,tempG,temp1,temp2,K[1],iData[1]);
+ CSHA256_16(tempG,tempH,tempA,tempB,tempC,tempD,tempE,tempF,temp1,temp2,K[2],iData[2]);
+ CSHA256_16(tempF,tempG,tempH,tempA,tempB,tempC,tempD,tempE,temp1,temp2,K[3],iData[3]);
+ CSHA256_16(tempE,tempF,tempG,tempH,tempA,tempB,tempC,tempD,temp1,temp2,K[4],iData[4]);
+ CSHA256_16(tempD,tempE,tempF,tempG,tempH,tempA,tempB,tempC,temp1,temp2,K[5],iData[5]);
+ CSHA256_16(tempC,tempD,tempE,tempF,tempG,tempH,tempA,tempB,temp1,temp2,K[6],iData[6]);
+ CSHA256_16(tempB,tempC,tempD,tempE,tempF,tempG,tempH,tempA,temp1,temp2,K[7],iData[7]);
+
+ CSHA256_16(tempA,tempB,tempC,tempD,tempE,tempF,tempG,tempH,temp1,temp2,K[8],iData[8]);
+ CSHA256_16(tempH,tempA,tempB,tempC,tempD,tempE,tempF,tempG,temp1,temp2,K[9],iData[9]);
+ CSHA256_16(tempG,tempH,tempA,tempB,tempC,tempD,tempE,tempF,temp1,temp2,K[10],iData[10]);
+ CSHA256_16(tempF,tempG,tempH,tempA,tempB,tempC,tempD,tempE,temp1,temp2,K[11],iData[11]);
+ CSHA256_16(tempE,tempF,tempG,tempH,tempA,tempB,tempC,tempD,temp1,temp2,K[12],iData[12]);
+ CSHA256_16(tempD,tempE,tempF,tempG,tempH,tempA,tempB,tempC,temp1,temp2,K[13],iData[13]);
+ CSHA256_16(tempC,tempD,tempE,tempF,tempG,tempH,tempA,tempB,temp1,temp2,K[14],iData[14]);
+ CSHA256_16(tempB,tempC,tempD,tempE,tempF,tempG,tempH,tempA,temp1,temp2,K[15],iData[15]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[16], iData[16], iData[14], iData[9], iData[1], iData[0]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[17], iData[17], iData[15], iData[10], iData[2], iData[1]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[18], iData[18], iData[16], iData[11], iData[3], iData[2]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[19], iData[19], iData[17], iData[12], iData[4], iData[3]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[20], iData[20], iData[18], iData[13], iData[5], iData[4]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[21], iData[21], iData[19], iData[14], iData[6], iData[5]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[22], iData[22], iData[20], iData[15], iData[7], iData[6]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[23], iData[23], iData[21], iData[16], iData[8], iData[7]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[24], iData[24], iData[22], iData[17], iData[9], iData[8]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[25], iData[25], iData[23], iData[18], iData[10], iData[9]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[26], iData[26], iData[24], iData[19], iData[11], iData[10]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[27], iData[27], iData[25], iData[20], iData[12], iData[11]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[28], iData[28], iData[26], iData[21], iData[13], iData[12]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[29], iData[29], iData[27], iData[22], iData[14], iData[13]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[30], iData[30], iData[28], iData[23], iData[15], iData[14]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[31], iData[31], iData[29], iData[24], iData[16], iData[15]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[32], iData[32], iData[30], iData[25], iData[17], iData[16]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[33], iData[33], iData[31], iData[26], iData[18], iData[17]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[34], iData[34], iData[32], iData[27], iData[19], iData[18]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[35], iData[35], iData[33], iData[28], iData[20], iData[19]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[36], iData[36], iData[34], iData[29], iData[21], iData[20]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[37], iData[37], iData[35], iData[30], iData[22], iData[21]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[38], iData[38], iData[36], iData[31], iData[23], iData[22]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[39], iData[39], iData[37], iData[32], iData[24], iData[23]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[40], iData[40], iData[38], iData[33], iData[25], iData[24]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[41], iData[41], iData[39], iData[34], iData[26], iData[25]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[42], iData[42], iData[40], iData[35], iData[27], iData[26]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[43], iData[43], iData[41], iData[36], iData[28], iData[27]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[44], iData[44], iData[42], iData[37], iData[29], iData[28]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[45], iData[45], iData[43], iData[38], iData[30], iData[29]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[46], iData[46], iData[44], iData[39], iData[31], iData[30]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[47], iData[47], iData[45], iData[40], iData[32], iData[31]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[48], iData[48], iData[46], iData[41], iData[33], iData[32]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[49], iData[49], iData[47], iData[42], iData[34], iData[33]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[50], iData[50], iData[48], iData[43], iData[35], iData[34]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[51], iData[51], iData[49], iData[44], iData[36], iData[35]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[52], iData[52], iData[50], iData[45], iData[37], iData[36]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[53], iData[53], iData[51], iData[46], iData[38], iData[37]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[54], iData[54], iData[52], iData[47], iData[39], iData[38]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[55], iData[55], iData[53], iData[48], iData[40], iData[39]);
+
+ CSHA256_48( tempA, tempB, tempC, tempD, tempE, tempF, tempG, tempH, temp1, temp2,
+ K[56], iData[56], iData[54], iData[49], iData[41], iData[40]);
+ CSHA256_48( tempH, tempA, tempB, tempC, tempD, tempE, tempF, tempG, temp1, temp2,
+ K[57], iData[57], iData[55], iData[50], iData[42], iData[41]);
+ CSHA256_48( tempG, tempH, tempA, tempB, tempC, tempD, tempE, tempF, temp1, temp2,
+ K[58], iData[58], iData[56], iData[51], iData[43], iData[42]);
+ CSHA256_48( tempF, tempG, tempH, tempA, tempB, tempC, tempD, tempE, temp1, temp2,
+ K[59], iData[59], iData[57], iData[52], iData[44], iData[43]);
+ CSHA256_48( tempE, tempF, tempG, tempH, tempA, tempB, tempC, tempD, temp1, temp2,
+ K[60], iData[60], iData[58], iData[53], iData[45], iData[44]);
+ CSHA256_48( tempD, tempE, tempF, tempG, tempH, tempA, tempB, tempC, temp1, temp2,
+ K[61], iData[61], iData[59], iData[54], iData[46], iData[45]);
+ CSHA256_48( tempC, tempD, tempE, tempF, tempG, tempH, tempA, tempB, temp1, temp2,
+ K[62], iData[62], iData[60], iData[55], iData[47], iData[46]);
+ CSHA256_48( tempB, tempC, tempD, tempE, tempF, tempG, tempH, tempA, temp1, temp2,
+ K[63], iData[63], iData[61], iData[56], iData[48], iData[47]);
+
+ iA+=tempA;
+ iB+=tempB;
+ iC+=tempC;
+ iD+=tempD;
+ iE+=tempE;
+ iF+=tempF;
+ iG+=tempG;
+ iH+=tempH;
+
+ iNl=0;
+ }
+
+/**
+ * According to the standard, the message must be padded to an
+ * even 512 bits. The first padding bit must be a '1'. The last
+ * 64 bits represent the length of the original message. All bits
+ * in between should be 0. This helper function will pad the
+ * message according to those rules by filling the iData array
+ * accordingly.
+ */
+void SHA256::PadMessage()
+ {
+ const TUint padByte = 0x80;
+
+ if(!(iNl&0x03))
+ {
+ iData[iNl >> 2] = 0;
+ }
+ iData[iNl >> 2] |= padByte << ((3 - iNl&0x03) << 3) ;
+
+ if (iNl >= (KSHA256BlockSize - 2*sizeof(TUint)))
+ {
+ if (iNl < (KSHA256BlockSize - sizeof(TUint)))
+ iData[(KSHA256BlockSize >> 2) - 1]=0;
+ Block();
+ memset(iData , 0 ,KSHA256BlockSize*sizeof(TUint));
+ }
+ else
+ {
+ const TUint offset=(iNl+4)>>2; //+4 to account for the word added in the
+ //switch statement above
+ memset((iData+offset), 0, ((KSHA256BlockSize - offset*sizeof(TUint))*sizeof(TUint)));
+ }
+
+ //Length in bits
+ TUint64 msgLength = iNh;
+
+ iData[(KSHA256BlockSize >> 2) - 2] = static_cast<TUint>((msgLength) >> 32);
+ iData[(KSHA256BlockSize >> 2) - 1] = static_cast<TUint>((msgLength & 0xFFFFFFFF));
+ }
+
+
+inline void SHA256::CopyWordToHash(TUint aVal, TInt aIndex)
+ {
+ TUint value = MakeWord(reinterpret_cast<TUint8*>(&aVal));
+ memmove(const_cast<TUint8*>(iHash.Ptr())+ (4*aIndex), &value, sizeof(aVal));
+ }
+
+
+ const TDesC8& SHA256::Final()
+ {
+ AddLength(iNl);
+ PadMessage();
+ Block();
+ //
+ // Generate hash value into iHash
+ //
+ CopyWordToHash(iA,0);
+ CopyWordToHash(iB,1);
+ CopyWordToHash(iC,2);
+ CopyWordToHash(iD,3);
+ CopyWordToHash(iE,4);
+ CopyWordToHash(iF,5);
+ CopyWordToHash(iG,6);
+ CopyWordToHash(iH,7);
+ Reset();
+ return iHash;
+ }
+
+
--- a/kernel/eka/kernel/sinit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/sinit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -21,6 +21,7 @@
#include <kernel/emi.h>
#include <kernel/sshbuf.h>
#include "platform.h"
+#include "securerng.h"
#ifdef __VC32__
#pragma setlocale("english")
@@ -46,6 +47,7 @@
TInt SupervisorThread(TAny*);
TInt DebuggerInit();
+extern TInt InitialiseEntropyBuffers();
extern const SNThreadHandlers EpocThreadHandlers;
@@ -392,6 +394,7 @@
K::Fault(K::EInit3Failed);
P::StartExtensions();
+ M::Init4();
K::StartKernelServer();
return 0;
}
@@ -442,6 +445,14 @@
r=K::StartTickQueue();
if (r!=KErrNone)
return r;
+
+ // Initilize the Secure RNG.
+ SecureRNG = new DSecureRNG;
+
+ // Initialise entropy buffers for secure RNG
+ r=InitialiseEntropyBuffers();
+ if (r!=KErrNone)
+ return r;
// Third phase initialisation of ASIC/Variant
// This enables the system tick and millisecond timer
@@ -450,9 +461,6 @@
// Mark the super page signature valid
P::SetSuperPageSignature();
- // Initialise the random pool
- K::Randomize();
-
return KErrNone;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/srandombuff.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,204 @@
+/**
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL " http://www.eclipse.org/legal/epl-v10.html ".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* eka\kernel\srandombuff.cpp
+*
+*/
+
+#include <kernel/kern_priv.h>
+#include <assp.h>
+#include "kernel/securerng.h"
+
+const TInt KWordIndexBitMask = 0x1FFF; // bottom 13 bits holds buffer word index
+const TInt KEntropyCountBitShift = 14; // top 18 bits holds entropy count
+const TUint KEntropyBufferThresholdWords = KEntropyBufferSizeWords * 3/4;
+
+/**
+ Adds a single bit to the random pool used to generate random numbers.
+
+ @deprecated use Kern::RandomSalt(TUint32 aEntropyData, TUint aBitsOfEntropy) or Kern::RandomSalt(TUint64 aEntropyData, TUint aBitsOfEntropy) instead
+
+ @param aBitOfSalt The least significant bit of this value is added to the random pool.
+
+ @pre Can be used in a device driver.
+*/
+EXPORT_C void Kern::RandomSalt(TUint32 aBitOfSalt)
+ {
+ // Check if RNG needs more entropy.
+ if (SecureRNG->SecureRNGIdle())
+ return;
+
+ Kern::RandomSalt(aBitOfSalt, 1);
+ }
+
+
+/**
+ Adds 32 bits of data, using the entropy estimate provided, to the random pool used to generate random numbers.
+
+ @param aEntropyData The 32 bits of data to be added to the random pool.
+ @param aBitsOfEntropy An estimate of the number of bits of entropy contained in the 32 bits of data.
+
+ @pre aBitsOfEntropy must be >=0 and <=32.
+ @pre Can be used in a device driver.
+*/
+EXPORT_C void Kern::RandomSalt(TUint32 aEntropyData, TUint aBitsOfEntropy)
+ {
+ // Check if RNG needs more entropy.
+ if (SecureRNG->SecureRNGIdle())
+ return;
+
+ __ASSERT_ALWAYS((TUint)aBitsOfEntropy <= 32, K::PanicKernExec(EEntropyEstimateOutOfRange));
+
+ TUint32 addcounts = (aBitsOfEntropy << KEntropyCountBitShift) + 1; // top 18 bits holds entropy count, plus 1 to increment buffer word index
+
+ TInt irq = NKern::DisableAllInterrupts();
+
+ TInt currentcpu = NKern::CurrentCpu();
+
+ TUint32 currentstatus = __e32_atomic_load_acq32(&K::EntropyBufferStatus[currentcpu]);
+ TUint32 nextword = currentstatus & KWordIndexBitMask; // bottom 13 bits holds buffer word index
+
+ if(nextword < KEntropyBufferSizeWords)
+ {
+ K::EntropyBuffer[currentcpu][nextword] = aEntropyData;
+ __e32_atomic_add_ord32(&K::EntropyBufferStatus[currentcpu], addcounts);
+ }
+
+ NKern::RestoreInterrupts(irq);
+
+ TUint32 entropycount = (currentstatus + addcounts) >> KEntropyCountBitShift; // top 18 bits holds entropy count
+ if((nextword < KEntropyBufferSizeWords) && (entropycount >= KReseedThreshold || nextword > KEntropyBufferThresholdWords))
+ {
+ if (NKern::CurrentContext() == NKern::EInterrupt)
+ K::EntropyBufferDfc.Add();
+ else
+ K::EntropyBufferDfc.Enque();
+ }
+ }
+
+
+/**
+ Adds 64 bits of data, using the entropy estimate provided, to the random pool used to generate random numbers.
+
+ @param aEntropyData The 64 bits of data to be added to the random pool.
+ @param aBitsOfEntropy An estimate of the number of bits of entropy contained in the 32 bits of data.
+
+ @pre aBitsOfEntropy must be >=0 and <=64.
+ @pre Can be used in a device driver.
+*/
+EXPORT_C void Kern::RandomSalt(TUint64 aEntropyData, TUint aBitsOfEntropy)
+ {
+ // Check if RNG needs more entropy.
+ if (SecureRNG->SecureRNGIdle())
+ return;
+
+ __ASSERT_ALWAYS((TUint)aBitsOfEntropy <= 64, K::PanicKernExec(EEntropyEstimateOutOfRange));
+
+ TUint32 addcounts = (aBitsOfEntropy << KEntropyCountBitShift) + 2; // top 18 bits holds entropy count, plus 2 to increment buffer word index
+
+ TInt irq = NKern::DisableAllInterrupts();
+
+ TInt currentcpu = NKern::CurrentCpu();
+
+ TUint32 currentstatus = __e32_atomic_load_acq32(&K::EntropyBufferStatus[currentcpu]);
+ TUint32 nextword = currentstatus & KWordIndexBitMask; // bottom 13 bits holds buffer word index
+
+ if((nextword + 1) < KEntropyBufferSizeWords)
+ {
+ K::EntropyBuffer[currentcpu][nextword] = I64LOW(aEntropyData);
+ K::EntropyBuffer[currentcpu][nextword+1] = I64HIGH(aEntropyData);
+ __e32_atomic_add_ord32(&K::EntropyBufferStatus[currentcpu], addcounts);
+ }
+
+ NKern::RestoreInterrupts(irq);
+
+ TUint32 entropycount = (currentstatus + addcounts) >> KEntropyCountBitShift; // top 18 bits holds entropy count
+ if((nextword < KEntropyBufferSizeWords) && (entropycount >= KReseedThreshold || nextword > KEntropyBufferThresholdWords))
+ {
+ if (NKern::CurrentContext() == NKern::EInterrupt)
+ K::EntropyBufferDfc.Add();
+ else
+ K::EntropyBufferDfc.Enque();
+ }
+ }
+
+
+#if defined(__EPOC32__)
+
+EXPORT_C void Interrupt::AddTimingEntropy()
+ {
+ // This function should only be called from Interrupt context otherwise timing may be predictable.
+ CHECK_PRECONDITIONS(MASK_NOT_THREAD|MASK_NOT_IDFC, "Interrupt::AddTimingEntropy()");
+
+ // Check if RNG needs more entropy.
+ if (SecureRNG->SecureRNGIdle())
+ return;
+
+ TUint32 timestamp = NKern::FastCounter();
+
+ Kern::RandomSalt(timestamp, 1);
+ }
+
+#endif
+
+extern void DrainEntropyBuffers(TAny*)
+ {
+ TUint32 wordsavailable = 0;
+ TUint32 wordscopied;
+ TUint32 currentstatus;
+ TBool result = 0;
+
+ for(TInt cpu = (NKern::NumberOfCpus() - 1); cpu >= 0; --cpu)
+ {
+ wordscopied = 0;
+ currentstatus = __e32_atomic_load_acq32(&K::EntropyBufferStatus[cpu]);
+
+ // if this CPU's buffer is empty then skip processing
+ if(currentstatus == 0) continue;
+
+ do
+ {
+ wordsavailable = currentstatus & KWordIndexBitMask;
+
+ memcpy(&K::TempEntropyBuffer[wordscopied], &K::EntropyBuffer[cpu][wordscopied], (wordsavailable - wordscopied)*4);
+
+ wordscopied = wordsavailable;
+
+ result = __e32_atomic_cas_ord32(&K::EntropyBufferStatus[cpu], ¤tstatus, 0);
+ }
+ while(!result);
+
+ SecureRNG->AddEntropy((TUint8*)&K::TempEntropyBuffer[0], wordscopied*4, currentstatus >> KEntropyCountBitShift);
+ }
+ }
+
+
+extern TInt InitialiseEntropyBuffers()
+ {
+ TInt numcpus = NKern::NumberOfCpus();
+
+ // Allocate space for all cpu buffers and store pointer to beginning as CPU 0 buffer.
+ K::EntropyBuffer[0] = (TUint32*)Kern::Alloc(KEntropyBufferSizeWords * numcpus * 4);
+
+ // Initialise pointers for remaining cpus
+ for(TInt cpu = 1; cpu < numcpus; ++cpu)
+ {
+ K::EntropyBuffer[cpu] = K::EntropyBuffer[0] + (cpu * KEntropyBufferSizeWords);
+ }
+
+ // Initialise DFC
+ K::EntropyBufferDfc.SetDfcQ(K::SvMsgQ);
+
+ return KErrNone;
+ }
--- a/kernel/eka/kernel/stest.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/kernel/stest.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -17,6 +17,7 @@
#include <kernel/kern_priv.h>
#include "kern_test.h"
+#include "securerng.h"
#ifdef _DEBUG
class TTestCallback: public TUserModeCallback
@@ -60,9 +61,9 @@
TInt r = KErrNotSupported;
(void)aFunc; (void)a1; (void)a2; (void)a3;
-#ifdef _DEBUG
switch(aFunc)
{
+#ifdef _DEBUG
case EUserModeCallbackSleep:
{
// a1 is a DThread*. We add a user mode callback to that thread
@@ -85,8 +86,18 @@
NKern::ThreadLeaveCS();
break;
}
+#endif
+ case ERNGReseedHook:
+ {
+ // a1 is a function which wants to be called with arg a2 when the RNG is reseeded.
+ // Used to test if reseeds are sufficiently frequent.
+ SecureRNG->SetReseedHook((void(*)(TAny*))a1, a2);
+ break;
+ }
+ default:
+ // To stop compiler warnings about unhandled enum cases in release builds
+ break;
}
-#endif
return r;
}
--- a/kernel/eka/memmodel/emul/win32/minit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/emul/win32/minit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -67,6 +67,11 @@
__KTRACE_OPT2(KBOOT,KMMU,Kern::Printf("M::Init3"));
}
+void M::Init4()
+ {
+ // Fourth phase MMU initialisation - Not required on this memory model.
+ }
+
// kernel heap construction
void P::KernelInfo(TProcessCreateInfo& aInfo, TAny*& aStack, TAny*& aHeap)
--- a/kernel/eka/memmodel/epoc/direct/minit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/direct/minit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -84,6 +84,11 @@
// Third phase MMU initialisation
}
+void M::Init4()
+ {
+ // Fourth phase MMU initialisation - Not required on this memory model.
+ }
+
TInt M::InitSvHeapChunk(DChunk* aChunk, TInt aSize)
{
DMemModelChunk* pC=(DMemModelChunk*)aChunk;
--- a/kernel/eka/memmodel/epoc/flexible/minit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/minit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -18,6 +18,9 @@
#include "mmboot.h"
#include "cache_maintenance.h"
+#include "mmu/mmu.h"
+#include "mmu/mpager.h"
+
extern void DoProcessSwitch();
@@ -52,6 +55,12 @@
MM::Init3();
}
+void M::Init4()
+ {
+ // Fourth phase MMU initialisation
+ ThePager.InitCache();
+ }
+
TInt M::InitSvHeapChunk(DChunk* aChunk, TInt aSize)
{
--- a/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -503,8 +503,54 @@
case EMemAttNormalCached:
texcb = KArmV6MemAttWBWAWBWA;
break;
- default:
- __NK_ASSERT_ALWAYS(0); // undefined memory type
+ case EMemAttKernelInternal4:
+ case EMemAttPlatformSpecific5:
+ case EMemAttPlatformSpecific6:
+ case EMemAttPlatformSpecific7:
+ {
+ TUint32 cachingAttr = InternalCache::TypeToCachingAttributes((TMemoryType)(attr&EMemoryAttributeTypeMask));
+ switch (cachingAttr)
+ {
+ case EMapAttrFullyBlocking:
+ texcb = KArmV6MemAttSO;
+ break;
+ case EMapAttrBufferedNC:
+ texcb = KArmV6MemAttSD;
+ break;
+ default:
+ {
+ //attr describes normal mapping
+ //set texcb to b1BBAA where AA is internal and BB is external caching
+ // TYPE AA/BB
+ // uncached 0
+ // WBWA 1
+ // WTRA 2
+ // WBRA 3
+ texcb = 0x10;
+ switch (cachingAttr&EMapAttrL1CacheMask)
+ {
+ case EMapAttrL1Uncached: break;
+ #if defined(__CPU_ARM1136_ERRATUM_399234_FIXED)
+ case EMapAttrCachedWTRA: texcb |= 2;break; // It is OK to use WT memory
+ #else
+ case EMapAttrCachedWTRA:;break; // Erratum not fixed. Use uncached memory instead
+ #endif
+ case EMapAttrCachedWBRA: texcb |= 3; break;
+ default: texcb |= 1;//fully cached (WBWA)
+ }
+ switch (cachingAttr&EMapAttrL2CacheMask)
+ {
+ case EMapAttrL2Uncached: break;
+ case EMapAttrL2CachedWTRA: texcb |= 8;break;
+ case EMapAttrL2CachedWBRA: texcb |= 0xc; break;
+ default: texcb |= 4;//fully cached (WBWA)
+ }
+ }
+ }
+ }
+ break;
+ default:
+ __NK_ASSERT_ALWAYS(0); // undefined memory type
texcb = KArmV6MemAttSO;
break;
}
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mm.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mm.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -905,9 +905,6 @@
// initialise address spaces...
DAddressSpace::Init2();
- // init pager...
- ThePager.Init2();
-
TheMmu.Init2Final();
}
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1435,7 +1435,7 @@
{
TRACE(("DVirtualPinMapping::New(0x%x)",aMaxCount));
DVirtualPinMapping* self = new DVirtualPinMapping;
- if(aMaxCount)
+ if(self && aMaxCount)
{
// pages have been reserved for our use.
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mobject.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mobject.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -506,9 +506,17 @@
if(self)
{
new (self) DPageTables(aMemory,numPts,aPteType);
+ // Add this page tables object to the memory object before we update any
+ // page table entries. To ensure that if any of aMemory's pages with
+ // corresponding page table entries in self are moved during Construct(),
+ // DCoarseMemory::RemapPage() will be able to find the page table entries
+ // to update via iPageTables.
+ __NK_ASSERT_DEBUG(!aMemory->iPageTables[aPteType]);
+ aMemory->iPageTables[aPteType] = self;
TInt r = self->Construct();
if(r!=KErrNone)
{
+ aMemory->iPageTables[aPteType] = 0;
self->Close();
self = 0;
}
@@ -1689,11 +1697,6 @@
{
// allocate a new one if required...
tables = DPageTables::New(this, iSizeInPages, aPteType);
- if (tables)
- {
- __NK_ASSERT_DEBUG(!iPageTables[aPteType]);
- iPageTables[aPteType] = tables;
- }
}
return tables;
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -50,14 +50,26 @@
DPager::DPager()
: iMinimumPageCount(0), iMaximumPageCount(0), iYoungOldRatio(0),
- iYoungCount(0),iOldCount(0),iNumberOfFreePages(0)
+ iYoungCount(0),iOldCount(0),
+#ifdef _USE_OLDEST_LISTS
+ iOldestCleanCount(0),
+#endif
+ iNumberOfFreePages(0), iReservePageCount(0), iMinimumPageLimit(0)
{
}
-void DPager::Init2()
+void DPager::InitCache()
{
- TRACEB(("DPager::Init2()"));
+ //
+ // This routine doesn't acquire any mutexes because it should be called before the system
+ // is fully up and running. I.e. called before another thread can preempt this.
+ //
+ TRACEB(("DPager::InitCache()"));
+ // If any pages have been reserved then they will have already been allocated and
+ // therefore should be counted as part of iMinimumPageCount.
+ __NK_ASSERT_DEBUG(iReservePageCount == iMinimumPageCount);
+ __NK_ASSERT_DEBUG(!CacheInitialised());
#if defined(__CPU_ARM)
@@ -104,85 +116,92 @@
__NK_ASSERT_DEBUG(KMinOldPages<=iAbsoluteMinPageCount/2);
- // initialise live list...
- TUint minimumPageCount = 0;
- TUint maximumPageCount = 0;
-
+ // Read any paging config data.
SDemandPagingConfig config = TheRomHeader().iDemandPagingConfig;
- iMinimumPageCount = KDefaultMinPages;
- if(minimumPageCount)
- iMinimumPageCount = minimumPageCount;
- if(config.iMinPages)
- iMinimumPageCount = config.iMinPages;
- if(iMinimumPageCount<iAbsoluteMinPageCount)
- iMinimumPageCount = iAbsoluteMinPageCount;
- iInitMinimumPageCount = iMinimumPageCount;
-
- iMaximumPageCount = KMaxTInt;
- if(maximumPageCount)
- iMaximumPageCount = maximumPageCount;
- if(config.iMaxPages)
- iMaximumPageCount = config.iMaxPages;
- if (iMaximumPageCount > KAbsoluteMaxPageCount)
- iMaximumPageCount = KAbsoluteMaxPageCount;
- iInitMaximumPageCount = iMaximumPageCount;
-
+ // Set the list ratios...
iYoungOldRatio = KDefaultYoungOldRatio;
if(config.iYoungOldRatio)
iYoungOldRatio = config.iYoungOldRatio;
- TInt ratioLimit = (iMinimumPageCount-KMinOldPages)/KMinOldPages;
- if(iYoungOldRatio>ratioLimit)
- iYoungOldRatio = ratioLimit;
-
#ifdef _USE_OLDEST_LISTS
iOldOldestRatio = KDefaultOldOldestRatio;
if(config.iSpare[2])
iOldOldestRatio = config.iSpare[2];
#endif
- iMinimumPageLimit = (iMinYoungPages * (1 + iYoungOldRatio)) / iYoungOldRatio;
- if(iMinimumPageLimit<iAbsoluteMinPageCount)
+ // Set the minimum page counts...
+ iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio
+ + DPageReadRequest::ReservedPagesRequired();
+
+ if(iMinimumPageLimit < iAbsoluteMinPageCount)
iMinimumPageLimit = iAbsoluteMinPageCount;
- TRACEB(("DPager::Init2() live list min=%d max=%d ratio=%d",iMinimumPageCount,iMaximumPageCount,iYoungOldRatio));
-
- if(iMaximumPageCount<iMinimumPageCount)
- __NK_ASSERT_ALWAYS(0);
-
- //
- // This routine doesn't acquire any mutexes because it should be called before the system
- // is fully up and running. I.e. called before another thread can preempt this.
- //
-
- // Calculate page counts
+ if (K::MemModelAttributes & (EMemModelAttrRomPaging | EMemModelAttrCodePaging | EMemModelAttrDataPaging))
+ iMinimumPageCount = KDefaultMinPages;
+ else
+ {// No paging is enabled so set the minimum cache size to the minimum
+ // allowable with the current young old ratio.
+ iMinimumPageCount = iMinYoungPages * (iYoungOldRatio + 1);
+ }
+
+ if(config.iMinPages)
+ iMinimumPageCount = config.iMinPages;
+ if(iMinimumPageCount < iAbsoluteMinPageCount)
+ iMinimumPageCount = iAbsoluteMinPageCount;
+ if (iMinimumPageLimit + iReservePageCount > iMinimumPageCount)
+ iMinimumPageCount = iMinimumPageLimit + iReservePageCount;
+
+ iInitMinimumPageCount = iMinimumPageCount;
+
+ // Set the maximum page counts...
+ iMaximumPageCount = KMaxTInt;
+ if(config.iMaxPages)
+ iMaximumPageCount = config.iMaxPages;
+ if (iMaximumPageCount > KAbsoluteMaxPageCount)
+ iMaximumPageCount = KAbsoluteMaxPageCount;
+ iInitMaximumPageCount = iMaximumPageCount;
+
+
+ TRACEB(("DPager::InitCache() live list min=%d max=%d ratio=%d",iMinimumPageCount,iMaximumPageCount,iYoungOldRatio));
+
+ // Verify the page counts are valid.
+ __NK_ASSERT_ALWAYS(iMaximumPageCount >= iMinimumPageCount);
TUint minOldAndOldest = iMinimumPageCount / (1 + iYoungOldRatio);
- if(minOldAndOldest < KMinOldPages)
- __NK_ASSERT_ALWAYS(0);
- if (iMinimumPageCount < minOldAndOldest)
- __NK_ASSERT_ALWAYS(0);
+ __NK_ASSERT_ALWAYS(minOldAndOldest >= KMinOldPages);
+ __NK_ASSERT_ALWAYS(iMinimumPageCount >= minOldAndOldest);
+
+ // Need at least iMinYoungPages pages mapped to execute worst case CPU instruction
TUint minYoung = iMinimumPageCount - minOldAndOldest;
- if(minYoung < iMinYoungPages)
- __NK_ASSERT_ALWAYS(0); // Need at least iMinYoungPages pages mapped to execute worst case CPU instruction
+ __NK_ASSERT_ALWAYS(minYoung >= iMinYoungPages);
+
+ // Verify that the young old ratio can be met even when there is only the
+ // minimum number of old pages.
+ TInt ratioLimit = (iMinimumPageCount-KMinOldPages)/KMinOldPages;
+ __NK_ASSERT_ALWAYS(iYoungOldRatio <= ratioLimit);
+
#ifdef _USE_OLDEST_LISTS
// There should always be enough old pages to allow the oldest lists ratio.
TUint oldestCount = minOldAndOldest / (1 + iOldOldestRatio);
- if (!oldestCount)
- __NK_ASSERT_ALWAYS(0);
+ __NK_ASSERT_ALWAYS(oldestCount);
#endif
+
iNumberOfFreePages = 0;
iNumberOfDirtyPages = 0;
- // Allocate RAM pages and put them all on the old list
+ // Allocate RAM pages and put them all on the old list.
+ // Reserved pages have already been allocated and already placed on the
+ // old list so don't allocate them again.
RamAllocLock::Lock();
iYoungCount = 0;
+#ifdef _USE_OLDEST_LISTS
iOldCount = 0;
-#ifdef _USE_OLDEST_LISTS
- iOldestCleanCount = 0;
iOldestDirtyCount = 0;
+ __NK_ASSERT_DEBUG(iOldestCleanCount == iReservePageCount);
+#else
+ __NK_ASSERT_DEBUG(iOldCount == iReservePageCount);
#endif
Mmu& m = TheMmu;
- for(TUint i=0; i<iMinimumPageCount; i++)
+ for(TUint i = iReservePageCount; i < iMinimumPageCount; i++)
{
// Allocate a single page
TPhysAddr pagePhys;
@@ -197,10 +216,11 @@
}
RamAllocLock::Unlock();
+ __NK_ASSERT_DEBUG(CacheInitialised());
#ifdef _USE_OLDEST_LISTS
- TRACEB(("DPager::Init2() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
+ TRACEB(("DPager::InitCache() end with young=%d old=%d oldClean=%d oldDirty=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iOldestCleanCount,iOldestDirtyCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
#else
- TRACEB(("DPager::Init2() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
+ TRACEB(("DPager::InitCache() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
#endif
}
@@ -1688,6 +1708,8 @@
TInt DPager::ResizeLiveList(TUint aMinimumPageCount, TUint aMaximumPageCount)
{
TRACE(("DPager::ResizeLiveList(%d,%d) current young=%d old=%d min=%d free=%d max=%d",aMinimumPageCount,aMaximumPageCount,iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
+ __NK_ASSERT_DEBUG(CacheInitialised());
+
if(!aMaximumPageCount)
{
aMinimumPageCount = iInitMinimumPageCount;
@@ -1705,6 +1727,8 @@
MmuLock::Lock();
+ __NK_ASSERT_ALWAYS(iYoungOldRatio!=0);
+
// Make sure aMinimumPageCount is not less than absolute minimum we can cope with...
iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio
+ DPageReadRequest::ReservedPagesRequired();
@@ -2190,11 +2214,6 @@
return r;
iBuffer = MM::MappingBase(bufferMapping);
- // ensure there are enough young pages to cope with new request object...
- r = ThePager.ResizeLiveList();
- if(r!=KErrNone)
- return r;
-
return r;
}
@@ -2406,6 +2425,7 @@
{
TRACEB(("Kern::InstallPagingDevice(0x%08x) name='%s' type=%d",aDevice,aDevice->iName,aDevice->iType));
+ __NK_ASSERT_DEBUG(!ThePager.CacheInitialised());
__NK_ASSERT_ALWAYS(aDevice->iReadUnitShift <= KPageShift);
TInt r = KErrNotSupported; // Will return this if unsupported device type is installed
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.h Sun Mar 14 13:15:32 2010 +0000
@@ -29,9 +29,14 @@
{
public:
DPager();
- void Init2();
+ void InitCache();
void Init3();
+ FORCE_INLINE TBool CacheInitialised()
+ {
+ return iYoungOldRatio && iMinimumPageLimit;
+ }
+
FORCE_INLINE TUint NumberOfFreePages()
{
return iNumberOfFreePages;
--- a/kernel/eka/memmodel/epoc/moving/minit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/moving/minit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -54,6 +54,11 @@
m.Init3();
}
+void M::Init4()
+ {
+ // Fourth phase MMU initialisation - Not required on this memory model.
+ }
+
TInt M::InitSvHeapChunk(DChunk* aChunk, TInt aSize)
{
TInt r;
--- a/kernel/eka/memmodel/epoc/multiple/minit.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/multiple/minit.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -49,6 +49,11 @@
m.Init3();
}
+void M::Init4()
+ {
+ // Fourth phase MMU initialisation - Not required on this memory model.
+ }
+
TInt M::InitSvHeapChunk(DChunk* aChunk, TInt aSize)
{
TInt r;
--- a/kernel/eka/memmodel/epoc/putils.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/memmodel/epoc/putils.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -428,11 +428,6 @@
static const TUint32 KMapAttrType2 = 0x80000000;
static const TUint32 KMapAttrTypeShift = 26;
-#if defined(__CPU_MEMORY_TYPE_REMAPPING)
-extern TUint32 PrimaryRegionRemapRegister();
-extern TUint32 NormalMemoryRemapRegister();
-#endif
-
EXPORT_C TMappingAttributes2::TMappingAttributes2(TMemoryType aType,
TBool aUserAccess,
TBool aWritable,
--- a/kernel/eka/release.txt Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/release.txt Sun Mar 14 13:15:32 2010 +0000
@@ -1,3 +1,120 @@
+Version 2.00.2075
+=================
+(Made by vfebvre 26/01/2010)
+
+1. josezhou
+ 1. DEF143803 COPY of DEF143562:No error note about connected USB HUB shown
+ 2. DEF143802 copied open for submission:EDHO-7Y3AAD, USB connection:
+ 3. DEF143804 COPY of DEF143568:USB using an obsoleted API to allocate endpoint resource
+ 4. DEF143799 COPY of DEF142812: SMP-Panic in the TDfcQue::ThreadFunction when USB channel is
+ 5. DEF143800 COPY of DEF142888: SMP-t_usbdi test case 1231 failed
+
+2. ange
+ 1. PDEF143797 Precondition is not met when USB OTG driver use Kernel API
+
+3. vfebvre
+ 1. MINOR_CHANGE Fixed test code for File Header Relocation
+
+
+Version 2.00.2074
+=================
+(Made by vfebvre 25/01/2010)
+
+1. djkovace
+ 1. DEF143683 Fix PL310 erratum 727915
+
+2. dogunjum
+ 1. DEF137221 NE1 PCI driver not confirmed SMPSAFE automatic test case missing
+
+3. vfebvre
+ 1. DEF143067 BTracex_ldd causing missing file warning in CTS77 image creation - TSW Defect
+
+
+Version 2.00.2073
+=================
+(Made by vfebvre 25/01/2010)
+
+1. mmoate
+ 1. MILESTONE: SymTB9.2, GT0660, MS3.8, DS.1456
+ REQ427:125 Cryptographically-Strong Random Number Generator [PREQ211]
+
+
+Version 2.00.2072
+=================
+(Made by vfebvre 25/01/2010)
+
+1. vfebvre
+ 1. MINOR_CHANGE Update required to base_e32.mrp for Header Relocation
+
+
+Version 2.00.2071
+=================
+(Made by vfebvre 21/01/2010)
+
+1. ryharkin
+ 1. PDEF143852 - TConsoleKey missing iPointerNumber
+ The text window server class TConsoleKey is missing the iPointerNumber member value
+
+
+Version 2.00.2070
+=================
+(Made by vfebvre 18/01/2010)
+
+1. shamaden
+ 1. DEF143440 t_heap fails when KHeapMinCellSize = 16
+
+2. necliffo
+ 1. DEF143882: SALM-7ZQN53 WDP: EMMC drive not mountable as Mass Storage
+
+3. gcochran
+ 1. DEF143458: E32 T_CODEPAGING test is not support large page cache (TB9.2) TSW: EYGL-7T38TL
+
+4. vfebvre
+ 1. DEF142990 Change to Make Files - Causing OS Base Build Failure
+
+
+Version 2.00.2069
+=================
+(Made by vfebvre 15/01/2010)
+
+1. martai
+ 1. DEF143580: t_fuzzldr crashes/hangs on FMM and Datapaged ROMs
+ 2. DEF143441: FMM: Minimise size of live list when demand paging disabled
+
+2. tommarti
+ 1. Fix for DEF140936: T_WDPSTRESS fails on NaviEngine SMPPAGE/SMPKERNEL
+
+
+Version 2.00.2068
+=================
+(Made by vfebvre 15/01/2010)
+
+1. djkovace
+ 1. PDEF143736 OOM defect in DVirtualPinMapping::New
+ 2. PDEF143812 Support platform specific mappings on 1136
+
+2. necliffo
+ 1. DEF143340 JPLS-7XXEAC: eMMC initialisation fails with Samsung 32GB
+ 2. DEF143593 WDP: Phone does not boot if SWAP drive is corrupted
+
+3. martai
+ 1. DEF142714: Frequent T_RAMDEFRAG failures observed on the H4
+
+4. vfebvre
+ 1. PDEF143659 Bootstrap.flm and related bld.inf changes not submitted to the MCL
+
+5. marisood
+ 1. DEF143212: Missing M&FS files from Symbian Foundation due to IP classifications
+
+
+Version 2.00.2067
+=================
+(Made by vfebvre 12/01/2010)
+
+1. cnotton
+ 1. MINOR_CHANGE Fixed some smaller compile issues with split and relocation header changes.
+
+
Version 2.00.2066
=================
(Made by vfebvre 11/01/2010)
--- a/kernel/eka/rombuild/ost.iby Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/rombuild/ost.iby Sun Mar 14 13:15:32 2010 +0000
@@ -17,7 +17,6 @@
#ifndef OST_IBY
#define OST_IBY
-#include <btrace.iby>
//Put kernel side DLLs in the core image on NAND configurations
//since that's where the majority of the client code will also be.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/rombuild/rom.flm Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Symbian. All rights reserved.
+#
+
+# macro for all the rules
+define rom
+
+FINAL::
+ifeq ($(OSTYPE),unix)
+ $(call startrule,rom) \
+ echo "This is not supported currently"; \
+ $(call endrule,rom)
+else
+ $(call startrule,rom) \
+ $(PERL) $(EPOCROOT)/sf/os/kernelhwsrv/kernel/eka/rombuild/rom_sbs.pl --variant=$(REE_TARGET) --inst=$(PLATFORM) --build=$(CFG) --type=$(TYPE) --clean --name=$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG).img \
+ $(call endrule,rom)
+endif
+
+FINAL::
+ $(call startrule,copy) \
+ mv rom.oby $(EPOCROOT)/epoc32/rom/$(REE_TARGET)/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG)_rom.oby; \
+ mv ROMBUILD.LOG $(EPOCROOT)/epoc32/rom/$(REE_TARGET)/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG)_ROMBUILD.LOG; \
+ mv $(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG).img $(EPOCROOT)/epoc32/rom/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG).img; \
+ $(call endrule,copy)
+
+endef
+
+# expand
+$(eval $(rom))
+
+# The items produced by this FLM:
+RELEASEABLES:=$(EPOCROOT)/epoc32/rom/$(REE_TARGET)/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG)_rom.oby $(EPOCROOT)/epoc32/rom/$(REE_TARGET)/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG)_ROMBUILD.LOG $(EPOCROOT)/epoc32/rom/$(REE_TARGET)_$(TYPE)_$(PLATFORM)_$(CFG).img
+
+## What targets -- declare the files produced here
+$(eval $(call whatmacro, $(RELEASEABLES)))
+## Clean up
+$(eval $(call GenerateStandardCleanTarget, $(RELEASEABLES)))
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/rombuild/rom.meta Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,10 @@
+# Meta information for the syborg extension template
+#
+# Copyright (c) 2009 Symbian Foundation Ltd. All rights reserved.
+#
+
+platform armv5
+makefile gnumake
+techstream base
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/rombuild/rom.xml Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+#
+# Copyright (c) 2009 Symbian Foundation.
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
+# which accompanies this distribution, and is available
+# at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
+#
+# Initial Contributors:
+# Symbian Foundation - initial contribution.
+#
+# Contributors:
+#
+# Description: Implementation of generic image generation for target using SBS/Raptor
+#
+-->
+<!-- Extension interfaces : replacements for Template Extension Makefiles -->
+
+<build xmlns="http://symbian.com/xml/build" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symbian.com/xml/build ../../schema/build/2_0.xsd">
+ <interface name="base.rom" extends="Symbian.KernelFLM" flm="rom.flm">
+ <param name="REE_TARGET"/>
+ <param name="TYPE"/>
+ </interface>
+</build>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/rombuild/rom_sbs.pl Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,875 @@
+#!perl
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+# rom.pl - Build a rom
+#
+# Pre-processes the .oby/iby files then invokes rombuild.exe
+# (or other specified builder)
+
+# First, read our config file
+
+use strict;
+use Getopt::Long;
+use Cwd;
+
+#Getopt::Long::Configure("ignore_case");
+my %opts=();
+my $param_count = scalar(@ARGV);
+my $result = GetOptions (\%opts, "assp=s",
+ "inst=s",
+ "type=s",
+ "variant=s",
+ "build=s",
+ "conf=s",
+ "name=s",
+ "modules=s",
+ "xabi=s",
+ "clean",
+ "quiet",
+ "help",
+ "_debug",
+ "zip",
+ "symbol",
+ "noheader",
+ "kerneltrace=s",
+ "rombuilder=s",
+ "define=s@",
+ "rofsbuilder=s",
+ "compress",
+ );
+
+my (@assps, @builds, %variants, @templates, %flags, %insts, %zip, %builder);
+my $main;
+my $kmain;
+my $toroot;
+my $e32path;
+my $rombuildpath;
+my $euserdir;
+my $elocldir;
+my $kbdir;
+my $romname;
+my $single;
+my $smain;
+my $pagedCode;
+my $debug = $opts{_debug};
+my $quiet;
+$quiet = $opts{quiet} unless $debug;
+
+my $drive;
+
+# discover where this script is running from to set the $toroot and $e32path variables
+
+my $toolpath;
+my $Epoc32Path;
+my $EpocRoot;
+my $drive;
+my $BasePath;
+
+BEGIN {
+
+ $EpocRoot = $ENV{EPOCROOT};
+ die "ERROR: Must set the EPOCROOT environment variable.\n" if (!defined($EpocRoot));
+ print "Environmental epocroot - >$EpocRoot<\n";
+ $EpocRoot =~ s-/-\\-go; # for those working with UNIX shells
+ if ($EpocRoot =~ /^([a-z]:)(.*)$/i)
+ {
+ # Raptor style: Drive letter and trailing \\ removed
+ $drive = $1;
+ $EpocRoot = "$2\\";
+ $ENV{EPOCROOT} = $EpocRoot;
+ }
+ die "ERROR: EPOCROOT must be an absolute path, " .
+ "not containing a drive letter.\n" if ($EpocRoot !~ /^\\/);
+ die "ERROR: EPOCROOT must not be a UNC path.\n" if ($EpocRoot =~ /^\\\\/);
+ die "ERROR: EPOCROOT must end with a backslash.\n" if ($EpocRoot !~ /\\$/);
+ die "ERROR: EPOCROOT must specify an existing directory.\n" if (!-d $EpocRoot);
+
+ # The cpp needed a drive apparently
+ my $cwd = Cwd::cwd();
+ $cwd =~ /^(.)/;
+ $drive = "$1:" unless $drive;
+ print "epocroot = >$EpocRoot<\n";
+ print "drive = >$drive<\n";
+
+ my $fp0 = $0;
+ $cwd =~ s/\//\\/g;
+ $fp0 =~ s/\//\\/g;
+ unless ($fp0 =~ /^([A-Za-z]:)?\\/) {
+ if ($cwd =~ /\\$/) {
+ $fp0 = "$cwd$fp0";
+ } else {
+ $fp0 = "$cwd\\$fp0";
+ }
+ }
+
+ my @path = split(/\\/, $cwd);
+ shift(@path);
+ $toroot = ('..\\') x @path;
+ $e32path = $fp0;
+ $e32path =~ s/\\kernelhwsrv\\kernel\\eka\\rombuild\\rom\.pl$//i;
+ $e32path =~ s/^[A-Za-z]://;
+ $rombuildpath = $toroot."sf\\os\\kernelhwsrv\\kernel\\eka\\rombuild";
+ $Epoc32Path = $toroot;
+ $Epoc32Path =~ s/\\$//;
+ $Epoc32Path .= $EpocRoot . "epoc32";
+ $toolpath = "$Epoc32Path\\tools\\";
+ push @INC, $toolpath;
+ $BasePath = $toroot . $e32path;
+}
+
+use E32Plat;
+{
+ Plat_Init($toolpath);
+}
+
+if ($debug) {
+ print "EpocRoot = $EpocRoot\n";
+ print "Epoc32Path = $Epoc32Path\n";
+ print "drive = $drive\n";
+ print "toolpath = $toolpath\n";
+ print "toroot = $toroot\n";
+ print "e32path = $e32path\n";
+ print "rombuildpath = $rombuildpath\n";
+ print "BasePath = $BasePath\n";
+}
+
+my $cppflags="-P -undef -traditional -lang-c++ -nostdinc -iwithprefixbefore $rombuildpath -I $rombuildpath -I $drive$Epoc32Path ";
+
+# Include variant hrh file defines when processing oby and ibys with cpp
+# (Code copied from \\EPOC\master\cedar\generic\tools\romkit\tools\buildrom.pm -
+# it used relative path to the working dir but we are using absolute path seems neater)
+use E32Variant;
+use Pathutl;
+my $variantMacroHRHFile = Variant_GetMacroHRHFile();
+if($variantMacroHRHFile){
+ # Using absolute paths so must include drive letter otherwise cpp will fail
+ # Also adding the directory containing the HRH file to main includes paths in
+ # case it includes files
+ my $variantFilePath = Path_Split('Path',$variantMacroHRHFile);
+ $cppflags .= " -I $drive$variantFilePath -include $drive$variantMacroHRHFile";
+}
+
+if($param_count == 0 || $opts{'help'} || !$result) {
+ usage();
+ exit 0;
+}
+
+# Now check that the options we have make sense
+
+checkopts();
+
+if (!$quiet) {
+ print "Starting directory: ", Cwd::cwd(), "\n";
+ print <<EOF;
+OPTIONS:
+\tTYPE: $opts{'type'}
+\tVARIANT: $opts{'variant'}
+\tINSTRUCTION SET: $opts{'inst'}
+\tBUILD: $opts{'build'}
+\tMODULES: $opts{'modules'}
+EOF
+}
+
+#Pick out the type file
+my $skel;
+
+if (-e "$opts{'type'}.oby") {
+ $skel="$opts{'type'}.oby";
+} elsif (-e "$rombuildpath\\$opts{'type'}.oby") {
+ $skel="$rombuildpath\\$opts{'type'}.oby";
+} else {
+ die "Can't find type file for type $opts{'type'}, $!";
+}
+
+print "Using type file $skel\n" if !$quiet;
+
+# If clean is specified, zap all the image and .oby files
+
+if($opts{'clean'}) {
+ unlink glob("*.img");
+ unlink "rom.oby";
+ unlink "rombuild.log";
+ unlink glob("*.rofs");
+ unlink "rofsbuild.log";
+}
+
+# Now pre-pre-process this file to point to the right places for .ibys
+# Unfortunately cpp won't do macro replacement in #include strings, so
+# we have to do it by hand
+
+my $k = $opts{kerneltrace};
+
+if ($opts{assp}=~/^m(\S+)/i) {
+ $kbdir="kb$1";
+ $kbdir="kbarm" if (lc $1 eq 'eig');
+} else {
+ $kbdir="kb$opts{assp}";
+}
+$single=1 if ($opts{assp}=~/^s(\S+)/i);
+
+if ($single) {
+ # Hackery to cope with old compiler
+ if ($main eq 'MARM') {
+ $smain='SARM';
+ } else {
+ $smain="S$main";
+ }
+} else {
+ $smain=$main;
+}
+
+open(X, "$skel") || die "Can't open type file $skel, $!";
+open(OUT, "> rom1.tmp") || die "Can't open output file, $!";
+
+# First output the ROM name
+print OUT "\nromname=$romname\n";
+while(<X>) {
+ s/\#\#ASSP\#\#/$opts{'assp'}/;
+ s/\#\#VARIANT\#\#/$opts{'variant'}/;
+ s/\#\#BUILD\#\#/$opts{'build'}/;
+ s/\#\#MAIN\#\#/$main/;
+ s/\#\#KMAIN\#\#/$kmain/;
+ s/\#\#E32PATH\#\#/$e32path/;
+ s/\#\#BASEPATH\#\#/$BasePath/;
+ s/\#\#EUSERDIR\#\#/$euserdir/;
+ s/\#\#ELOCLDIR\#\#/$elocldir/;
+ s/\#\#KBDIR\#\#/$kbdir/;
+ print OUT;
+}
+
+close X;
+close OUT;
+
+# Use cpp to pull in include chains and replace defines
+
+my $defines = "";
+$defines .= "-D MAIN=$main ";
+$defines .= "-D KMAIN=$kmain ";
+$defines .= "-D EUSERDIR=$euserdir ";
+$defines .= "-D ELOCLDIR=$elocldir ";
+$defines .= "-D E32PATH=$e32path ";
+$defines .= "-D BASEPATH=$BasePath ";
+$defines .= "-D EPOCROOT=$EpocRoot ";
+$defines .= "-D SMAIN=$smain " if $smain;
+
+foreach (@{$opts{'define'}}) {
+ my @array=split(/,/,$_);
+ foreach (@array) {
+ $defines.="-D ".uc $_." ";
+ $pagedCode = 1 if $_ eq 'PAGED_CODE';
+ }
+ }
+
+if ($opts{'modules'}) {
+ my @array=split(/,/,$opts{'modules'});
+ foreach (@array) {
+ $defines.="-D ".uc $_." ";
+ }
+ }
+
+foreach (keys %opts) {
+ next if ($_ eq 'name');
+ next if ($_ eq 'modules');
+ next if ($_ eq 'zip');
+ next if ($_ eq 'symbol');
+ next if ($_ eq 'kerneltrace');
+ next if ($_ eq 'define');
+ $defines.="-D ".uc $_."=".$opts{$_}." ";
+ $defines.="-D ".uc $_."_".$opts{$_}." ";
+}
+
+$defines.="-D SINGLE " if ($single);
+
+sub IsRVCTBuild($) {
+ my ($build)=@_;
+ return 1 if ($build =~ /^ARMV/i);
+ my @customizations = Plat_Customizations('ARMV5');
+ return 1 if (grep /$build/, @customizations);
+ return 0;
+}
+
+$defines.="-D RVCT " if (IsRVCTBuild($main));
+
+print "Using defines $defines\n" if !$quiet;
+
+my $ret=1;
+my $cppcmd;
+if($opts{'build'}=~/^u/i) {
+ # Unicode build
+ $cppcmd = "$Epoc32Path/gcc/bin/cpp $cppflags -D UNICODE $defines rom1.tmp rom2.tmp";
+} else {
+ $cppcmd = "cpp $cppflags $defines rom1.tmp rom2.tmp";
+}
+print "Executing CPP:\n\t$cppcmd\n" if $debug;
+$ret = system($cppcmd);
+die "ERROR EXECUTING CPP\n" if $ret;
+
+# Zap any ## marks REMS or blank lines
+
+cleanup("rom2.tmp", "rom3.tmp", $k);
+
+# scan tmp file and generate auxiliary files, if required
+open TMP, "rom3.tmp" or die("Can't open rom3.tmp\n");
+my $line;
+while ($line=<TMP>)
+ {
+ if ($line=~/\s*gentestpaged/i) {
+ genfile("paged"); }
+ if ($line=~/\s*gentestnonpaged/i) {
+ genfile("nonpaged"); }
+ }
+
+parsePatchData("rom3.tmp", "rom4.tmp");
+
+# break down the oby file into rom, rofs and extensions oby files
+
+my $oby_index =0;
+my $dumpfile="rom.oby";
+my $rofs=0;
+my $extension=0;
+my $corerofsname="";
+open DUMPFILE, ">$dumpfile" or die("Can't create $dumpfile\n");
+my $line;
+open TMP, "rom4.tmp" or die("Can't open rom4.tmp\n");
+while ($line=<TMP>)
+ {
+ if ($line=~/^\s*rofsname/i)
+ {
+ close DUMPFILE; # close rom.oby or previous rofs#/extension#.oby
+ $oby_index=1;
+ $corerofsname=$line;
+ $corerofsname =~ s/rofsname\s*=\s*//i; # save core rofs name
+ $corerofsname =~ s/\s*$//g; # remove trailing \n
+ unlink $corerofsname || print "unable to delete $corerofsname";
+ my $dumpfile="rofs".$rofs.".oby";
+ $rofs++;
+ open DUMPFILE, ">$dumpfile" or (close TMP and die("Can't create $dumpfile\n"));
+ }
+
+ if ($line=~/^\s*coreimage/i)
+ {
+ close DUMPFILE; # close rofs.oby
+ if ($oby_index ne 1) {
+ close TMP;
+ die "Must specify ROFS image before ROFS extension\n";
+ }
+ my $name=$line;
+ $name =~ s/coreimage\s*=\s*//i; # read core rofs name
+ $name =~ s/\s*$//g; # remove trailing \n
+ if ($name ne $corerofsname) {
+ close TMP;
+ die "This extension does not relate to previous ROFS\n";
+ }
+ $oby_index=33; # open window
+ my $dumpfile="extension".$extension.".oby";
+ $extension++;
+ open DUMPFILE, ">$dumpfile" or (close TMP and die("Can't create $dumpfile\n"));
+ }
+
+ if ($line=~/^\s*extensionrofs/i)
+ {
+ $oby_index=3 if ($oby_index eq 2);
+ }
+
+ if (($oby_index eq 2) && !($line=~/^\s*$/)) {
+ close TMP;
+ die "Bad ROFS extension specification\n";
+ }
+ print DUMPFILE $line;
+ $oby_index=2 if ($oby_index eq 33); # close window
+ }
+close DUMPFILE;
+close TMP;
+
+# For paged roms that use rofs, move all data= lines in rom which are not 'paging_unmovable' to rofs, so that paged ram-loaded code
+# is automatically put into rofs
+rename('rom.oby', 'rom4.tmp') || die;
+
+open(IN, 'rom4.tmp') || die "Can't read rom4.tmp";
+open(ROM, '>rom.oby') || die "Can't write to rom.oby";
+
+if ($oby_index >= 1 && $pagedCode) {
+ open(ROFS, '>>rofs0.oby') || die "Can't append to rofs0.oby";
+}
+
+while ($line=<IN>)
+{
+ if(($oby_index >= 1) && ($pagedCode) && ($line=~/^\s*data\s*=/) && !($line=~/\.*paging_unmovable\s*/)) {
+ print ROFS $line;
+ }
+ else {
+ $line=~s/paging_unmovable//;
+ print ROM $line;
+ }
+}
+
+close IN;
+close ROM;
+
+if ($oby_index >= 1 && $pagedCode) {
+ close ROFS;
+}
+ unlink 'rom4.tmp';
+
+my $flags;
+
+foreach (@{$flags{$opts{'assp'}}}) {
+ $flags.=" -$_";
+}
+
+if($opts{'noheader'}) {
+ $flags.=" -no-header";
+}
+
+if($opts{'compress'}) {
+ $flags.=" -compress";
+}
+
+my $builder = $opts{'rombuilder'};
+$builder = "rombuild" unless ($builder);
+
+
+
+print "$builder $flags -type-safe-link -S rom.oby 2>&1\n\n";
+
+open(Y, "$builder $flags -type-safe-link -S rom.oby 2>&1 |") ||
+ die "Can't start $builder command, $!";
+
+my $nerrors=0;
+my $nwarnings=0;
+
+while(<Y>) {
+ my $error=(/^error:/i);
+ my $warning=(/^warning:/i);
+ print if ($error or $warning or !$quiet);
+ $nerrors++ if ($error);
+ $nwarnings++ if ($warning);
+}
+
+print "\nGenerated .oby file is rom.oby\n" if !$quiet;
+print "\nGenerated image file is $romname\n" if (!$nerrors);
+
+my$rerrors;
+my $rofsbuilder;
+if ($rofs) {
+ $rofsbuilder = $opts{'rofsbuilder'};
+ $rofsbuilder = "rofsbuild" unless ($rofsbuilder);
+ for(my $i=0;$i<$rofs;++$i) {
+ print "Executing $rofsbuilder on main rofs\n" if !$quiet;
+ my $image="rofs".$i.".oby";
+ system("$rofsbuilder $image");
+ if ($? != 0)
+ {
+ print "$rofsbuilder $image returned $?\n";
+ $rerrors++;
+ }
+ rename "rofsbuild.log", "rofs$i.log"
+ }
+}
+
+if ($rofs and $extension) {
+ for(my $i=0;$i<$extension;++$i) {
+ print "Executing $rofsbuilder on extension rofs\n" if !$quiet;
+ my $image="extension".$i.".oby";
+ system("$rofsbuilder $image");
+ if ($? != 0)
+ {
+ print "$rofsbuilder $image returned $?\n";
+ $rerrors++;
+ }
+ rename "rofsbuild.log", "extension$i.log"
+ }
+}
+
+if ($nerrors) {
+ print "\n\n Errors found during $builder!!\n\nLeaving tmp files\n";
+} elsif ($nwarnings) {
+ print "\n\n Warnings during $builder!!\n\nLeaving tmp files\n";
+} elsif ($rerrors) {
+ print "\n\n Errors during $rofsbuilder!!\n\nLeaving tmp files\n";
+} else {
+ unlink glob("*.tmp") if !$debug;
+}
+if ($opts{zip} or $zip{$opts{assp}}) {
+ my $zipname=$romname;
+ $zipname =~ s/\.(\w+)$/\.zip/i;
+ unlink $zipname;
+ system("zip $zipname $romname");
+}
+if ($opts{symbol}) {
+ my $logname=$romname;
+ $logname =~ s/\.(\w+)$/\.log/i;
+ my $obyname=$romname;
+ $obyname =~ s/\.(\w+)$/\.oby/i;
+ unlink $logname;
+ unlink $obyname;
+ system("rename rombuild.log $logname");
+ system("rename rom.oby $obyname");
+ system("maksym $logname");
+}
+
+if ($nerrors || $nwarnings || $rerrors) {
+ exit 4;
+}
+
+exit 0;
+
+
+################################ Subroutines ##################################
+
+sub usage {
+ print <<EOT;
+
+rom <options>
+
+Generate a rom image for the specified target, along with a rom.oby file
+that can be fed to (a) rombuild to regenerate the image.
+
+The following options are required:
+ --variant=<variant> e.g. --variant=assabet
+ --inst=<instruction set> e.g. --inst=arm4
+ --build=<build> e.g. --build=udeb
+ --type=<type of rom>
+ tshell for a text shell rom
+ e32tests for a rom with e32tests
+ f32tests for rom with f32tests
+ alltests for all the tests
+
+The following are optional:
+ --name=<image name> Give image file specified name
+ --noheader Pass -no-header option on to rombuild
+ --help This help message.
+ --clean Remove existing generated files first
+ --quiet Be less verbose
+ --modules=<comma separated list> List of additional modules for this ROM
+ --define=<comma separated list> List of CPP macros to define
+
+Options may be specified as a short abbreviation
+e.g. -b udeb instead of --build udeb
+
+EOT
+}
+
+sub cleanup($$$) {
+ my ($in, $out, $k) = @_;
+ my ($line, $lastblank);
+
+ open(OUTPUT_FILE, "> $out") or die "Cannot open $out for output";
+ open(INPUT_FILE, "< $in") or die "Cannot open for $in input";
+
+ while ($line=<INPUT_FILE>) {
+ $line=~s/##//g;
+
+ # file=\epoc32\... ==> file=%EPOCROOT%\epoc32\...
+ $line =~ s/(=\s*)\\epoc32/\1${EpocRoot}Epoc32/i;
+
+ # Now compress blank lines down to one
+
+ if($line=~/^\s*$/) {
+ if($lastblank) {
+ # Do nothing
+ } else {
+ # This is the first blank line
+ $lastblank=1;
+ print OUTPUT_FILE $line;
+ }
+ } else {
+ # Not blank
+ $lastblank=0;
+ if ($k and $line=~/^\s*kerneltrace/i) {
+ $line = "kerneltrace $k\n";
+ }
+ print OUTPUT_FILE $line if !($line=~/^\s*REM\s+/i);
+ }
+ }
+ close(INPUT_FILE);
+ close(OUTPUT_FILE);
+}
+
+sub IsSmp($) {
+ my %SmpKernelDirs=(
+ 'x86smp' => 1,
+ 'x86gmp' => 1,
+ 'arm4smp' => 1,
+ 'armv4smp' => 1,
+ 'armv5smp' => 1
+ );
+
+ my ($kdir) = @_;
+ return $SmpKernelDirs{lc $kdir};
+}
+
+sub checkopts {
+ unless($opts{variant}) { die "No Variant specified"; }
+ $opts{'build'}="UDEB" unless($opts{'build'});
+ $opts{'type'}="TSHELL" unless($opts{'type'});
+ $opts{'inst'}="ARM4" unless($opts{'inst'});
+
+ my $additional;
+ if ($opts{'modules'}) {
+ $additional="_".$opts{modules};
+ $additional=~ s/,/_/ig;
+ }
+ my $build=lc $opts{build};
+ my $inst=uc $opts{'inst'};
+ if ($inst eq "MARM") {
+ # Hackery to cope with old compiler
+ $main="MARM";
+ $euserdir="MARM";
+ $elocldir="MARM";
+ }
+ else {
+ $main=$inst;
+ if ($main eq "THUMB") {
+ $euserdir="ARMI";
+ } else {
+ $euserdir=$main;
+ }
+ if ($main eq "ARMI" or $main eq "THUMB") {
+ $elocldir="ARM4";
+ } else {
+ $elocldir=$main;
+ }
+ }
+ $kmain = $opts{'xabi'};
+ $kmain = $main unless ($kmain);
+ if (IsSmp($kmain)) {
+ $euserdir = $kmain;
+ }
+ if ($opts{name}) {
+ $romname=$opts{name};
+ } else {
+ $romname=uc($opts{variant}.$additional.$main);
+ if ($build=~/^\w*DEB$/i) {
+ $romname.='D';
+ }
+ $romname.='.IMG';
+ }
+}
+
+sub lookupFileInfo($$)
+{
+ my ($infile, $fullname) = @_;
+
+ my ($name, $ext) = $fullname =~ /^(.+)\.(\w+)$/ ? ($1, $2) : ($fullname, undef);
+
+ open TMP, $infile or die("Can't open $infile\n");
+ while(<TMP>)
+ {
+ $_ = lc;
+ if(/^\s*(\S+)\s*=\s*(\S+)\s+(\S+)/i)
+ {
+ my ($src, $dest) = ($2, $3);
+
+ my $destFullname = $dest =~ /^.*\\(.+)$/ ? $1 : $dest;
+ my ($destName, $destExt) = $destFullname =~ /^(.+?)\.(\w+)$/ ? ($1, $2) : ($destFullname, undef);
+
+ if ($destName eq $name && (!$ext || $ext eq $destExt))
+ {
+ close TMP;
+ return ($src, $dest);
+ }
+ }
+ }
+
+ die "patchdata: Can't find file $fullname\n";
+}
+
+sub lookupSymbolInfo($$)
+{
+ my ($file, $name) = @_;
+
+ open TMP, $file or die "Can't read $file\n";
+
+ # ignore local symbols.
+ while (<TMP> !~ /Global Symbols/) { }
+
+ while (<TMP>)
+ {
+ if (/^\s*(\S+)\s+(\S+)\s+data\s+(\S+)/i)
+ {
+ my ($symbol, $addr, $size) = ($1, $2, $3);
+ if ($symbol eq $name)
+ {
+ close TMP;
+ return ($addr, $size);
+ }
+ }
+
+ # This is a quick fix for RVCT 3.1, which uses the text "(EXPORTED)"
+ # in the map file. Here is an example:
+ #
+ # KHeapMinCellSize (EXPORTED) 0x0003d81c Data 4 mem.o(.constdata)
+ #
+ elsif (/^\s*(\S+)\s+\(exported\)\s+(\S+)\s+data\s+(\S+)/i)
+ {
+ my ($symbol, $addr, $size) = ($1, $2, $3);
+ if ($symbol eq $name)
+ {
+ close TMP;
+ return ($addr, $size);
+ }
+ }
+ }
+
+ die "patchdata: Can't find symbol $name\n";
+}
+
+sub parsePatchData($$)
+{
+ my ($infile, $outfile) = @_;
+
+ open IN, $infile or die("Can't read $infile\n");
+ open OUT, ">$outfile" or die("Can't write $outfile\n");
+
+ my $line;
+ while($line = <IN>)
+ {
+ if ($line =~ /^\s*patchdata\s+(.+?)\s*$/i)
+ {
+ if ($1 !~ /(\S+)\s*@\s*(\S+)\s+(\S+)\s*$/)
+ {
+ die "Bad patchdata command: $line\n";
+ }
+
+ my ($file, $symbol, $value) = (lc $1, $2, $3);
+ my ($srcFile, $destFile) = lookupFileInfo($infile, $file);
+ my ($index, $elementSize) = (undef, undef);
+ if ($symbol =~ s/:(\d+)\[(\d+)\]$//)
+ {
+ ($index, $elementSize) = ($2, $1);
+ $index = hex($index) if $index =~ /^0x/i;
+ }
+
+ if ($srcFile =~ /\\armv5(smp)?\\/i)
+ {
+ my ($symbolAddr, $symbolSize) = lookupSymbolInfo("$srcFile.map", $symbol);
+
+ my $max;
+ if (defined($index))
+ {
+ my $bytes;
+ $bytes = 1, $max = 0xff if $elementSize == 8;
+ $bytes = 2, $max = 0xffff if $elementSize == 16;
+ $bytes = 4, $max = 0xffffffff if $elementSize == 32;
+ die("patchdata: invalid element size $elementSize: $line\n") unless defined($bytes);
+
+ if ($bytes > 1 && (($symbolSize & ($bytes-1)) != 0))
+ {
+ die("patchdata: unexpected symbol size $symbolSize for array $symbol ($elementSize-bit elements)\n");
+ }
+
+ if ($index >= int($symbolSize / $bytes))
+ {
+ die("patchdata: index $index out of bounds for $symbol of $symbolSize bytes ($elementSize-bit elements)\n");
+ }
+
+ $symbolAddr = hex($symbolAddr) if $symbolAddr =~ /^0x/i;
+ $symbolAddr += $index * $bytes;
+ $symbolAddr = sprintf("0x%x", $symbolAddr);
+
+ $symbolSize = $bytes;
+ }
+ elsif ($symbolSize == 1) { $max = 0xff; }
+ elsif ($symbolSize == 2) { $max = 0xffff; }
+ elsif ($symbolSize == 4) { $max = 0xffffffff; }
+ else { die "patchdata: Unexpected symbol size $symbolSize for $symbol\n"; }
+
+ $value = hex($value) if $value =~ /^0x/i;
+ if ($value > $max)
+ {
+ print("Warning: Value overflow of $symbol\n");
+ $value &= $max;
+ }
+ $value = sprintf("0x%08x", $value);
+
+ $line = "patchdata $destFile addr $symbolAddr $symbolSize $value\n";
+ }
+ else
+ {
+ $line = "";
+ }
+
+ }
+
+ print OUT $line;
+ }
+
+ close IN;
+ close OUT;
+}
+
+sub genfile {
+ my $count=0;
+ if($_[0] eq 'paged') {
+ my $file='gentestpaged.txt';
+ unlink $file;
+ open(OUTFILE, ">$file") or die "Can't open output file, $!";
+ for(my $i=0;$i<50000;++$i) {
+ if(($i >5) && ($i % 40 ==0)) {
+ print OUTFILE "\n";
+ $count++;
+ }
+ if(($i+$count) % 5 ==0) {
+ print OUTFILE "SATOR ";
+ }
+ if(($i+$count) % 5 ==1) {
+ print OUTFILE "AREPO ";
+ }
+ if(($i+$count) % 5 ==2) {
+ print OUTFILE "TENET ";
+ }
+ if(($i+$count) % 5 ==3) {
+ print OUTFILE "OPERA ";
+ }
+ if(($i+$count) % 5 ==4) {
+ print OUTFILE "ROTAS ";
+ }
+ }
+ } else {
+ my $file='gentestnonpaged.txt';
+ unlink $file;
+ open(OUTFILE, ">$file") or die "Can't open output file, $!";
+ for(my $i=0;$i<20000;++$i) {
+ if(($i >5) && ($i % 40 ==0)) {
+ print OUTFILE "\n";
+ $count++;
+ }
+ if(($i+$count) % 4 ==0) {
+ print OUTFILE "STEP ";
+ }
+ if(($i+$count) % 4 ==1) {
+ print OUTFILE "TIME ";
+ }
+ if(($i+$count) % 4 ==2) {
+ print OUTFILE "EMIT ";
+ }
+ if(($i+$count) % 4 ==3) {
+ print OUTFILE "PETS ";
+ }
+ }
+ }
+}
+
+__END__
+
+# Tell emacs that this is a perl script even 'though it has a .bat extension
+# Local Variables:
+# mode:perl
+# tab-width:4
+# End:
+
--- a/kernel/eka/rombuild/utrace.iby Mon Mar 08 11:57:08 2010 +0000
+++ b/kernel/eka/rombuild/utrace.iby Sun Mar 14 13:15:32 2010 +0000
@@ -17,7 +17,6 @@
#ifndef UTRACE_IBY
#define UTRACE_IBY
-#include <btrace.iby>
//Put kernel side DLLs in the core image on NAND configurations
//since that's where the majority of the client code will also be.
--- a/kerneltest/e32test/defrag/t_ramdefrag.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/defrag/t_ramdefrag.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -575,6 +575,10 @@
UpdateRamInfo();
gEndRam = gFreeRam;
TESTDEBUG(test.Printf(_L("End RAM Free = 0x%x, End RAM Used = 0x%x\n"), gEndRam, gRamUsed));
+
+ // Ensure any asynchronous clean up operations complete before we move on
+ // to the next test.
+ UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
CheckRamDifference();
test.Printf(_L(" \n"));
}
@@ -1753,6 +1757,12 @@
//! 7. Allocate discardable pages by loading pages that are demand paged.
//! Check which zone the memory has been allocated to by checking the number of
//! discardable pages before and after the allocation has taken place.
+//! 8. Allocate a contiguous fixed page into a zone which is full of movable or discardable pages.
+//! 9. Allocate a large 1MB aligned chunk with as few pages as possible availiable for page tables,
+//! then clear to every page in the chunk. This is attempting to ensure that the chunk pages
+//! that have page tables associated to them are remapped correctly if the chunk pages have to be
+//! moved so page table pages to map other pages in the chunk are allocated in the most preferable
+//! ram zones.
//!
//! @SYMTestExpectedResults
//! 1. The memory has been allocated to the most preferred zone with the least amount of
@@ -1765,6 +1775,9 @@
//! 6. Extra page is placed in the next preferable to the "best"zone
//! 7. Memory is allocated to the most preferred zone with the least amount of
//! space accounting for the zone threshold for discardable pages.
+//! 8. The fixed page is allocated as it has moved or discarded a page.
+//! 9. The chunk is cleared succesfully.
+//!
//---------------------------------------------------------------------------------------------------------------------
TInt TestAllocStrategies()
{
@@ -2469,6 +2482,37 @@
skipTest8:
TestEnd();
+ test.Next(_L("Test9: Allocate a large 1MB aligned chunk and touch all its pages"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+
+ GetAllPageInfo();
+ const TUint KChunkBytes = 0x100000;
+ const TUint KChunkMask = KChunkBytes - 1;
+ TUint freeBytes = gTotalPageCount.iFreePages << gPageShift;
+ TUint chunkSize = freeBytes & ~KChunkMask;
+ // Fill as much memory as possible with fixed pages while still allowing the movable allocation to succeed.
+ // This should help force the page table allocation for the chunk to need to move pages.
+ TUint fixedSize = freeBytes - chunkSize;
+ r = KErrNoMemory;
+ while (r != KErrNone && fixedSize)
+ {
+ Ldd.FreeAllFixedPages();
+ fixedSize -= gPageSize;
+ test.Printf(_L("fixedSize 0x%x\n"), fixedSize);
+ r = Ldd.AllocateFixed(fixedSize >> gPageShift);
+ if (r != KErrNone)
+ break;
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, gChunkArraySize1, chunkSize);
+ }
+ if (r == KErrNone)
+ {
+ // Touch every page in the chunk.
+ memclr(gChunkArray1->Base(), chunkSize);
+ }
+ TestEnd(); // This will free any chunk and fixed pages.
+
test.End();
return KErrNone;
}
@@ -3805,6 +3849,8 @@
Ldd.FreeAllFixedPages();
TestEnd();
+ PrintPageInfo();
+
test.Next(_L("Test7: Defrag memory filled with discardable pages when the min cache size is reached\n"));
TestStart();
if (gPagedRom)
--- a/kerneltest/e32test/device/t_usb.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/device/t_usb.h Sun Mar 14 13:15:32 2010 +0000
@@ -86,10 +86,13 @@
TBool iBufferSizeChosen;
TBool iBandwidthPriorityChosen;
TBool iDMAChosen;
+ TBool iAllocateDma;
TBool iDoubleBufferingChosen;
+ TBool iAllocateDoubleBuffering;
TUint32 iBandwidthPriority;
TBool iSoftwareConnect;
TBool iHighSpeed;
+ TBool iResourceAllocationV2;
TBool iOtg;
TBool iVerbose;
};
--- a/kerneltest/e32test/device/t_usbapi.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/device/t_usbapi.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -60,6 +60,7 @@
static RUsbOtgDriver gOTG;
static TBool gSupportsOtg;
static TBool gSupportsHighSpeed;
+static TBool gSupportResouceAllocationV2;
static TBool gUsingHighSpeed;
static TBool gSoak;
static TChar gKeychar = 'a';
@@ -282,7 +283,7 @@
}
-static void TestResourceAllocation()
+static void TestResourceAllocationV1()
{
test.Start(_L("Test Endpoint Resource Allocation"));
@@ -347,7 +348,8 @@
// Global variable - we'll need this value later
gSupportsHighSpeed = d_caps().iHighSpeed;
-
+ gSupportResouceAllocationV2 = (d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2);
+
test.Printf(_L("### USB device capabilities:\n"));
test.Printf(_L("Number of endpoints: %d\n"), n);
test.Printf(_L("Supports Software-Connect: %s\n"),
@@ -364,8 +366,7 @@
(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
_S("yes") : _S("no"));
test.Printf(_L("Supports endpoint resource alloc scheme V2: %s\n"),
- (d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) ?
- _S("yes") : _S("no"));
+ gSupportResouceAllocationV2 ? _S("yes") : _S("no"));
test(n >= 2);
test.Printf(_L("(Device has sufficient endpoints.)\n"));
@@ -446,7 +447,10 @@
// Some UDCs won't allow endpoint resource manipulation once the hardware has been
// configured and turned on. So we do it here & now:
- TestResourceAllocation();
+ if (!gSupportResouceAllocationV2)
+ {
+ TestResourceAllocationV1();
+ }
// On the other hand, since some UDCs won't let us test many features which require
// register access until the USB hardware is powered up (and because it might start
@@ -504,6 +508,13 @@
r = gPort.ReleaseInterface(0);
test(r == KErrNone);
+ if (gSupportResouceAllocationV2)
+ {
+ test.Next(_L("setting resource allocation info on endpoint 1 with resource allocation scheme v2"));
+ ifc().iEndpointData[0].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DMA;
+ ifc().iEndpointData[0].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+ }
+
test.Next(_L("Setting interface"));
r = gPort.SetInterface(0, ifc);
test(r == KErrNone);
@@ -536,6 +547,18 @@
// Suspend thread to let things get stable on the bus.
User::After(2000000);
+ if (gSupportResouceAllocationV2)
+ {
+ test.Next(_L("endpoint 1 resource allocation results(resource allocation V2)"));
+ TBool res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
+ test.Printf(_L("Double Buffering on endpoint 1 %s\n"),
+ res ? _S("now allocated") : _S("not allocated"));
+
+ res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDMA);
+ test.Printf(_L("DMA on endpoint 1 %s\n"),
+ res ? _S("still allocated") : _S("not allocated"));
+ }
+
test.End();
}
--- a/kerneltest/e32test/device/t_usbco2.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/device/t_usbco2.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -31,7 +31,7 @@
_LIT(KFileName, "\\T_USBFILE.BIN");
_LIT(KActivePanic, "T_USB");
-static const TUint32 KTusbVersion = 20070524; // just an edit date really
+static const TUint32 KTusbVersion = 20091224; // just an edit date really
static const TUint8 KUsbrflctVersionMajor = 1; // the version we're compatible with
static const TUint8 KUsbrflctVersionMinor = 5;
static const TUint8 KUsbrflctVersionMicro = 0;
@@ -52,9 +52,12 @@
iBufferSizeChosen(EFalse),
iBandwidthPriorityChosen(EFalse),
iDMAChosen(EFalse),
+ iAllocateDma(EFalse),
iDoubleBufferingChosen(EFalse),
+ iAllocateDoubleBuffering(EFalse),
iSoftwareConnect(EFalse),
iHighSpeed(EFalse),
+ iResourceAllocationV2(EFalse),
iOtg(EFalse),
iVerbose(aVerboseOutput)
{}
@@ -112,7 +115,18 @@
return;
}
TUSB_PRINT("Created reader/writer");
-
+
+ // check for endpoint resource allocation v2 support
+ TUsbDeviceCaps d_caps;
+ r = iPort.DeviceCaps(d_caps);
+ if (r != KErrNone)
+ {
+ TUSB_PRINT1("Error %d on querying device capabilities", r);
+ User::Leave(-1);
+ return;
+ }
+ iResourceAllocationV2 = ((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
+
// Check for OTG support
TBuf8<KUsbDescSize_Otg> otg_desc;
r = iPort.GetOtgDescriptor(otg_desc);
@@ -373,14 +387,17 @@
}
TUSB_PRINT1("(Set to 0x%08X)", iBandwidthPriority);
iBandwidthPriorityChosen = ETrue;
-
- TUSB_PRINT("Configuring interface...");
- TInt r = SetupInterface();
- if (r != KErrNone)
+
+ if (!iResourceAllocationV2)
{
- TUSB_PRINT1("Error: %d. Stopping active scheduler...", r);
- CActiveScheduler::Stop();
- return;
+ TUSB_PRINT("Configuring interface...");
+ TInt r = SetupInterface();
+ if (r != KErrNone)
+ {
+ TUSB_PRINT1("Error: %d. Stopping active scheduler...", r);
+ CActiveScheduler::Stop();
+ return;
+ }
}
}
else if (!iDMAChosen)
@@ -389,15 +406,27 @@
switch (aChar)
{
case '1':
+ {
TUSB_PRINT("- Trying to deallocate endpoint DMA:\n");
- DeAllocateEndpointDMA(EEndpoint1);
- DeAllocateEndpointDMA(EEndpoint2);
+ if (!iResourceAllocationV2)
+ {
+ DeAllocateEndpointDMA(EEndpoint1);
+ DeAllocateEndpointDMA(EEndpoint2);
+ }
+ iAllocateDma = EFalse;
break;
+ }
case '2':
+ {
TUSB_PRINT("- Trying to allocate endpoint DMA:\n");
- AllocateEndpointDMA(EEndpoint1);
- AllocateEndpointDMA(EEndpoint2);
+ if (!iResourceAllocationV2)
+ {
+ AllocateEndpointDMA(EEndpoint1);
+ AllocateEndpointDMA(EEndpoint2);
+ }
+ iAllocateDma = ETrue;
break;
+ }
default:
TUSB_PRINT1("Not a valid input character: %c", aChar.operator TUint());
goto request_char;
@@ -410,20 +439,44 @@
switch (aChar)
{
case '1':
+ {
TUSB_PRINT("- Trying to deallocate Double Buffering:\n");
- DeAllocateDoubleBuffering(EEndpoint1);
- DeAllocateDoubleBuffering(EEndpoint2);
+ if (!iResourceAllocationV2)
+ {
+ DeAllocateDoubleBuffering(EEndpoint1);
+ DeAllocateDoubleBuffering(EEndpoint2);
+ }
+ iAllocateDoubleBuffering = EFalse;
break;
+ }
case '2':
+ {
TUSB_PRINT("- Trying to allocate Double Buffering:\n");
- AllocateDoubleBuffering(EEndpoint1);
- AllocateDoubleBuffering(EEndpoint2);
+ if (!iResourceAllocationV2)
+ {
+ AllocateDoubleBuffering(EEndpoint1);
+ AllocateDoubleBuffering(EEndpoint2);
+ }
+ iAllocateDoubleBuffering = ETrue;
break;
+ }
default:
TUSB_PRINT1("Not a valid input character: %c", aChar.operator TUint());
goto request_char;
}
iDoubleBufferingChosen = ETrue;
+
+ if (iResourceAllocationV2)
+ {
+ TUSB_PRINT("Configuring interface...");
+ TInt r = SetupInterface();
+ if (r != KErrNone)
+ {
+ TUSB_PRINT1("Error: %d. Stopping active scheduler...", r);
+ CActiveScheduler::Stop();
+ return;
+ }
+ }
// Everything chosen, so let's re-enumerate...
TUSB_PRINT("Enumeration...");
@@ -682,6 +735,20 @@
return KErrGeneral;
}
+ if (iResourceAllocationV2)
+ {
+ if (iAllocateDma)
+ {
+ ifc().iEndpointData[0].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DMA;
+ ifc().iEndpointData[1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DMA;
+ }
+ if (iAllocateDoubleBuffering)
+ {
+ ifc().iEndpointData[0].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+ ifc().iEndpointData[1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+ }
+ }
+
_LIT16(ifcname, "T_USB Test Interface (Default Setting 0)");
ifc().iString = const_cast<TDesC16*>(&ifcname);
ifc().iTotalEndpointsUsed = 2;
@@ -1775,6 +1842,7 @@
TUSB_PRINT1("Device State notifier: Alternate interface setting has changed: now %d",
iDeviceState & ~KUsbAlternateSetting);
}
+
Activate();
}
--- a/kerneltest/e32test/group/bld.inf Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/group/bld.inf Sun Mar 14 13:15:32 2010 +0000
@@ -37,10 +37,10 @@
../dll/d_ldrtst.h /epoc32/include/
-../nkernsa/interrupts.h /epoc32/include/nktest/ //
-../nkernsa/nkutils.h /epoc32/include/nktest/ //
-../nkernsa/utils.h /epoc32/include/nktest/ //
-../nkernsa/diag.h /epoc32/include/nktest/ //
+../nkernsa/interrupts.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(nktest/interrupts.h) //
+../nkernsa/nkutils.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(nktest/nkutils.h) //
+../nkernsa/utils.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(nktest/utils.h) //
+../nkernsa/diag.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(nktest/diag.h) //
../../../kernel/eka/include/e32huffman.h /epoc32/include/
@@ -69,6 +69,7 @@
../dll/oe/eabi/urel/t_oeexport1.exe /epoc32/release/armv5/urel/t_oeexport1.exe
../demandpaging/d_pagestress.h /epoc32/include/
+../pci/t_pci.h /epoc32/include/e32test/t_pci.h
../iic/iic_psl/i2c.h /epoc32/include/e32test/
../iic/iic_psl/spi.h /epoc32/include/e32test/
@@ -117,6 +118,7 @@
d_shbuf_client support
d_shbuf_own support
d_asid support
+d_entropysources support
#ifdef GENERIC_MARM
d_schedhook support
@@ -482,6 +484,11 @@
t_heapdb
t_kheap
+// Secure RNG tests
+t_securerng
+t_sha256
+t_entropysources
+
// /E32TEST/LFFS tests
t_lfsdrv2 manual
t_lfsdrvbm manual
@@ -999,3 +1006,6 @@
d_mmcsc support
#include "../hcr/hcr.inf"
+
+//pci tests
+t_pci
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/d_entropysources.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,34 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\group\d_entropysources.mmp
+//
+//
+
+#include "kernel/kern_ext.mmh"
+
+target d_entropysources.ldd
+targettype ldd
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude ../../../kernel/eka/include/kernel
+sourcepath ../random
+source d_entropysources.cpp
+
+start wins
+win32_headers
+end
+
+capability all
+vendorid 0x70000001
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_entropysources.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,30 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Tests whether the device has good enough entropy sources or not.
+//
+//
+
+TARGET t_entropysources.exe
+TARGETTYPE EXE
+UID 0x2000A3D2 0xA000D320
+VENDORID 0x70000001
+
+SOURCEPATH ../random
+SOURCE t_entropysources.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY euser.lib hal.lib
+SMPSAFE
+CAPABILITY all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_pci.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,27 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test/group/t_pci.mmp
+
+TARGET t_pci.exe
+TARGETTYPE EXE
+SOURCEPATH ../pci
+SOURCE t_pci.cpp
+LIBRARY euser.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+CAPABILITY ReadDeviceData WriteDeviceData
+
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_securerng.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,31 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Description:
+// e32test/group/t_securerng.mmp
+//
+
+
+TARGET t_securerng.exe
+TARGETTYPE EXE
+
+
+UID 0 0x2000A3D7
+
+SOURCEPATH ../random
+SOURCE t_securerng.cpp
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY euser.lib
+
+VENDORID 0x70000001
+SMPSAFE
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_sha256.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,36 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test/group/tsha256.mmp
+//
+//
+
+TARGET t_sha256.exe
+TARGETTYPE EXE
+
+
+UID 0 0x2000A3D7
+
+SOURCEPATH ../random
+SOURCE t_sha256.cpp
+SOURCE ../../../kernel/eka/kernel/sha256.cpp
+
+
+USERINCLUDE ../../../kernel/eka/include/kernel
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+LIBRARY euser.lib
+
+VENDORID 0x70000001
+SMPSAFE
--- a/kerneltest/e32test/heap/t_heap.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/heap/t_heap.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -529,7 +529,12 @@
for(TInt aSize2=(TInt)pHeap->AllocLen(aCell); aSize2>=0; aSize2--)
{
test(pHeap->ReAlloc(aCell, aSize2)!=NULL);
- test(((TInt)pHeap->AllocLen(aCell)>=aSize2)&&((TInt)pHeap->AllocLen(aCell)<=aSize2+KMinFreeSize));
+
+ test((TInt)pHeap->AllocLen(aCell)>=aSize2);
+
+ TInt aTmpSize2 = Max(_ALIGN_UP(aSize2 + RHeap::EAllocCellSize, KAlign), KMinFreeSize);
+
+ test((TInt)pHeap->AllocLen(aCell)<=aTmpSize2+KMinFreeSize);
}
pHeap->Check();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/test_thread.h Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,240 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Description: Some helper classes to assist with writing multi-threaded tests
+
+#ifndef TEST_THREAD_H
+#define TEST_THREAD_H
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32svr.h>
+#include <e32des8.h>
+#include <e32des8_private.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <e32std.h>
+#include <e32std_private.h>
+
+
+_LIT(KPciPanicCat, "test_thread.h");
+
+static const TInt KPciHeapSize=0x2000;
+
+enum TPciPanicCode
+ {
+ EThreadCreateFailed
+ };
+
+/**
+A utility class for running functions in other threads/processes
+*/
+class TTestRemote
+ {
+public:
+ virtual TInt WaitForExitL() = 0;
+ virtual ~TTestRemote()
+ {}
+
+ virtual void Rendezvous(TRequestStatus& aStatus) = 0;
+
+protected:
+ TTestRemote()
+ {}
+
+ static TInt RunFunctor(TAny* aFunctor)
+ {
+ TFunctor& functor = *(TFunctor*)aFunctor;
+ functor();
+ return KErrNone;
+ }
+
+ TRequestStatus iLogonStatus;
+ static TInt iCount;
+ };
+TInt TTestRemote::iCount=0;
+
+class TTestThread : public TTestRemote
+ {
+public:
+ TTestThread(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume=ETrue)
+ {
+ Init(aName, aFn, aData, aAutoResume);
+ }
+
+ /**
+ Run aFunctor in another thread
+ */
+ TTestThread(const TDesC& aName, TFunctor& aFunctor, TBool aAutoResume=ETrue)
+ {
+ Init(aName, RunFunctor, &aFunctor, aAutoResume);
+ }
+
+ ~TTestThread()
+ {
+ //RTest::CloseHandleAndWaitForDestruction(iThread);
+ iThread.Close();
+ }
+
+ void Resume()
+ {
+ iThread.Resume();
+ }
+
+ /**
+ If thread exited normally, return its return code
+ Otherwise, leave with exit reason
+ */
+ virtual TInt WaitForExitL()
+ {
+ User::WaitForRequest(iLogonStatus);
+ const TInt exitType = iThread.ExitType();
+ const TInt exitReason = iThread.ExitReason();
+
+ __ASSERT_ALWAYS(exitType != EExitPending, User::Panic(_L("TTestThread"),0));
+
+ if(exitType != EExitKill)
+ User::Leave(exitReason);
+
+ return exitReason;
+ }
+
+ virtual void Rendezvous(TRequestStatus& aStatus)
+ {
+ iThread.Rendezvous(aStatus);
+ }
+
+private:
+ void Init(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume)
+ {
+ TKName name(aName);
+ name.AppendFormat(_L("-%d"), iCount++);
+ TInt r=iThread.Create(name, aFn, KDefaultStackSize, KPciHeapSize, KPciHeapSize, aData);
+ if(r!=KErrNone)
+ {
+ RDebug::Printf("RThread::Create failed, code=%d", r);
+ User::Panic(KPciPanicCat, EThreadCreateFailed);
+ }
+
+ iThread.Logon(iLogonStatus);
+ __ASSERT_ALWAYS(iLogonStatus == KRequestPending, User::Panic(_L("TTestThread"),0));
+
+ if(aAutoResume)
+ iThread.Resume();
+ }
+
+ RThread iThread;
+ };
+
+class CTest : public CBase, public TFunctor
+ {
+public:
+ ~CTest()
+ {
+ iName.Close();
+ }
+
+ virtual void operator()()
+ {
+ RTest test(iName);
+ test.Start(iName);
+ for(TInt i=0; i<iIterations; i++)
+ {
+ test.Next(iName);
+ RunTest();
+ }
+ test.End();
+ }
+
+ virtual void RunTest() = 0;
+
+ virtual CTest* Clone() const = 0;
+
+ const TDesC& Name() const
+ {
+ return iName;
+ }
+
+protected:
+ CTest(const TDesC& aName, TInt aIterations)
+ :iIterations(aIterations)
+ {
+ iName.CreateL(aName);
+ }
+
+
+
+ CTest(const CTest& aOther)
+ :iIterations(aOther.iIterations)
+ {
+ iName.CreateL(aOther.iName);
+ }
+
+ //It would be useful to have an RTest member, but this can't be
+ //initialised untill the new thread is running as it will refer to
+ //the creating thread
+ RBuf iName;
+ const TInt iIterations;
+ };
+
+/**
+Make aNumberOfThreads copies of aTest and run
+each in its own thread
+
+@param test Reference to test object
+@param aTest Referance
+*/
+void MultipleTestRun(RTest& test, const CTest& aTest, TInt aNumberOfThreads)
+ {
+ RPointerArray<CTest> testArray;
+ RPointerArray<TTestThread> threadArray;
+
+ for(TInt i=0; i<aNumberOfThreads; i++)
+ {
+ test.Printf(_L("Create test thread"));
+ CTest* newTest = aTest.Clone();
+ test_NotNull(newTest);
+
+ TTestThread* thread = new TTestThread(aTest.Name(), *newTest);
+ test_NotNull(thread);
+
+ threadArray.AppendL(thread);
+ testArray.AppendL(newTest);
+ }
+
+ const TInt count = threadArray.Count();
+ for(TInt j=0; j<count; j++)
+ {
+ TTestThread* thread = threadArray[j];
+
+ TInt r = KErrNone;
+ TRAPD(leaveCode, r = thread->WaitForExitL());
+ if(leaveCode != KErrNone)
+ {
+ test.Printf(_L("Thread %d: Panic code:%d\n"), j, leaveCode);
+ test_KErrNone(leaveCode);
+ }
+
+ if(r!=KErrNone)
+ {
+ test.Printf(_L("Thread Number %d\n"), j);
+ test_KErrNone(r);
+ }
+ }
+
+ threadArray.ResetAndDestroy();
+ threadArray.Close();
+
+ testArray.ResetAndDestroy();
+ testArray.Close();
+ }
+
+#endif //TEST_THREAD_H
+
--- a/kerneltest/e32test/mmu/t_cache.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/mmu/t_cache.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -310,18 +310,17 @@
DoTest4(RCacheTestDevice::E_Normal_Cached, dC, timeNS, timeS);
test.Printf(_L("Normal_Cached %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
+ DoTest4(RCacheTestDevice::E_KernelInternal4, dC, timeNS, timeS);
+ test.Printf(_L("KernelInternal4 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
+ DoTest4(RCacheTestDevice::E_PlatformSpecific5, dC, timeNS, timeS);
+ test.Printf(_L("PlatSpecific5 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
+ DoTest4(RCacheTestDevice::E_PlatformSpecific6, dC, timeNS, timeS);
+ test.Printf(_L("PlatSpecific6 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
+ DoTest4(RCacheTestDevice::E_PlatformSpecific7, dC, timeNS, timeS);
+ test.Printf(_L("PlatSpecific7 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
+
if(CacheInfo.iMemoryRemapping)
{
- DoTest4(RCacheTestDevice::E_KernelInternal4, dC, timeNS, timeS);
- test.Printf(_L("KernelInternal4 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
- DoTest4(RCacheTestDevice::E_PlatformSpecific5, dC, timeNS, timeS);
- test.Printf(_L("PlatSpecific5 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
- DoTest4(RCacheTestDevice::E_PlatformSpecific6, dC, timeNS, timeS);
- test.Printf(_L("PlatSpecific6 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
- DoTest4(RCacheTestDevice::E_PlatformSpecific7, dC, timeNS, timeS);
- test.Printf(_L("PlatSpecific7 %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
-
-
DoTest4(RCacheTestDevice::E_InnerWT_Remapped, dC, timeNS, timeS);
test.Printf(_L("InnerWT_Remap %08xH\t%7d\t%7d\n"),dC.iActualMapAttr, timeNS, timeS);
DoTest4(RCacheTestDevice::E_InnerWBRA_Remapped, dC, timeNS, timeS);
--- a/kerneltest/e32test/mmu/t_codepaging.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/mmu/t_codepaging.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -698,7 +698,7 @@
r=file.BlockMap(info,start, -1,ETestDebug);
if (r!=KErrNone && r!=KErrCompletion)
- test.Printf(_L("Error %d: could not obtain block map\n"),r);
+ test.Printf(_L("Error %d: could not obtain block map for file %S\n"),r, &libname);
test(r==KErrNone || r==KErrCompletion);
TInt locDriveNumber=info.iLocalDriveNumber;
@@ -1746,7 +1746,18 @@
l.Close();
CopyDllsToSupportedDrives();
-
+
+ // Set Code Paging Cache to a known size compatable with this test
+ TInt pageSize = 0;
+ test_noError(UserHal::PageSizeInBytes(pageSize));
+ TUint cacheOriginalMin = 0, cacheOriginalMax = 0, cacheCurrentSize = 0;
+ const TUint kCacheNewMin = 64, kCacheNewMax = 256;
+ test.Printf(_L("Change cache size to Min:%d, Max:%d pages for duration of test\n"), kCacheNewMin, kCacheNewMax );
+
+ //store original values
+ DPTest::CacheSize(cacheOriginalMin, cacheOriginalMax, cacheCurrentSize);
+ test_KErrNone(DPTest::SetCacheSize(kCacheNewMin*pageSize, kCacheNewMax*pageSize));
+
Initialise();
StartOtherProcess(2, OtherProcess);
@@ -1755,6 +1766,11 @@
OtherProcess.Kill();
OtherProcess.Close();
+
+ //Restore the cache size to original values
+ test.Printf(_L("Reset cache size to original values Min:%d Max:%d pages\n"), cacheOriginalMin/pageSize, cacheOriginalMax/pageSize);
+ test_KErrNone(DPTest::SetCacheSize(cacheOriginalMin, cacheOriginalMax));
+
test.End();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pci/t_pci.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,865 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This is a test for the PCI driver, so far implemented only on the
+// Naviengine platform. It aims to test:
+// -That known values of data in config and memory space, on a given
+// device can be read as expected.
+// -That data can be written and modified in config and memory space
+// -PCI memory buffers mapped or allocated by the PCI driver work as
+// expected. These are
+// -DChunk created by PCI driver and accessible from PCI
+// -DPlatHwChunk created by PCI driver and accessible from PCI
+// -DChunk created externally, then mapped in to PCI memory space
+// There are tests to:
+// - Create and close each buffer. Heap checking ensures proper
+// cleanup
+// - Create and close multiple buffers from multiple threads.
+// This is an SMP focused test to check that the implementation
+// of the chunk manager and allocator in the driver are thread
+// safe. The tests should pass without triggering any assertions in
+// the driver's invariance checks.
+// - Write to buffers from software, and read back via the
+// system to PCI window, and vice-versa -- a loop-back test.
+// This checks that PCI buffers are indeed accessible to PCI devices.
+//
+// The tests require several pieces of PSL specific information:
+// - A TPciDevice containing the vendor and device IDs of a PCI device
+// to use for testing.
+// - TAddrSpaceTests which identify regions of a device's config and
+// memory space with known values, or which are known to be writable.
+//
+// The test driver grants access to the PCI API with the following
+// constructs:
+// - TUserConfigSpace and TUserMemorySpace, derived from TUserPciSpace,
+// which are user side equivalents of kernel-side objects allowing
+// accesses of different sizes to a PCI device's config space or
+// memory space.
+// - RPciChunk which is derived from and RChunk and corresponds to
+// a kernel-side DChunk, which in turn corresponds to a PCI chunk or
+// buffer. The test driver uses these for all PCI chunk types (a
+// "wrapper" DChunk is used to map the memory of a PCI DPlatHwChunk
+// to user side).
+//
+// Known Issues:
+// The test driver d_pci is intended to be platform independent but
+// for now still contains some PSL specific information .eg the test
+// info structure (which should really be passed up from the PSL) and
+// the address and size of the system to pci window. For now the
+// test driver code will remain in the Naviengine baseport directory.
+// If the PCI driver is ever ported to a new platform this can be
+// rectified.
+//
+//
+//
+#include "../misc/test_thread.h"
+#include <e32std.h>
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include "t_pci.h"
+#include <assp/naviengine/pci.h>
+
+class RPci;
+/**
+Extends RChunk to hold the PCI address
+associated with a chunk.
+*/
+class RPciChunk: public RChunk
+ {
+public:
+ TUint PciBase()
+ {
+ return iPciBaseAddr;
+ }
+
+ /**
+ Return the PCI accessible size
+ */
+ TInt Size() const
+ {
+ return iPciSize;
+ }
+
+private:
+ friend class RPci;
+ TUint iPciBaseAddr;
+ TInt iPciSize; //size of the region mapped into PCI
+ };
+
+typedef TInt (RPci::*ChunkOpenFn)(RPciChunk&, TInt, TRequestStatus*);
+
+class RPci : public RBusLogicalChannel
+ {
+public:
+ TInt Open();
+ TInt GetTestInfo(TPciTestInfo& aTestInfo);
+
+ TInt Open(const TPciDevice&);
+
+ TUint AccessConfigSpace(const TUserConfigSpace& aCs);
+ TUint AccessMemorySpace(const TUserMemorySpace& aMs);
+ TInt OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0);
+ TInt OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0);
+ TInt OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0);
+ TInt OpenPciWindowChunk(RChunk& aPciWindowChunk);
+ TInt RunUnitTests();
+private:
+ TInt DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus);
+ };
+
+inline TInt RPci::Open()
+ {
+ return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, NULL);
+ }
+
+inline TInt RPci::Open(const TPciDevice& aDevice)
+ {
+ TPckgC<TPciDevice> devicePkg(aDevice);
+ return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, &devicePkg);
+ }
+
+inline TInt RPci::GetTestInfo(TPciTestInfo& aTestInfo)
+ {
+ TPckg<TPciTestInfo> info(aTestInfo);
+ return DoControl(EGetTestInfo, &info);
+ }
+
+inline TInt RPci::RunUnitTests()
+ {
+ return DoControl(ERunUnitTests);
+ }
+
+TUint RPci::AccessConfigSpace(const TUserConfigSpace& aCs)
+ {
+ TPckgC<TUserConfigSpace> pkg(aCs);
+ return DoControl(EAccessConfigSpace, &pkg);
+ }
+
+TUint RPci::AccessMemorySpace(const TUserMemorySpace& aMs)
+ {
+ TPckgC<TUserMemorySpace> pkg(aMs);
+ return DoControl(EAccessMemorySpace, &pkg);
+ }
+
+TInt RPci::OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus)
+ {
+ return DoOpenPciChunk(aPciChunk, aPciChunkSize, EOpenPciDChunk, aStatus);
+ }
+
+TInt RPci::OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus)
+ {
+ return DoOpenPciChunk(aPciHwChunk, aPciChunkSize, EOpenPciPlatHwChunk, aStatus);
+ }
+
+TInt RPci::OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus)
+ {
+ return DoOpenPciChunk(aPciMappedChunk, aPciChunkSize, EOpenPciMappedChunk, aStatus);
+ }
+
+TInt RPci::OpenPciWindowChunk(RChunk& aPciWindowChunk)
+ {
+ TUint chunkHandle = DoControl(EOpenPciWindowChunk);
+ return aPciWindowChunk.SetReturnedHandle(chunkHandle);
+ }
+
+TInt RPci::DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus)
+ {
+ const TInt constPciChunkSize = aPciChunkSize;
+ TPciChunkCreateInfo info(constPciChunkSize, aPciChunk.iPciBaseAddr, aStatus);
+ TPckgC<TPciChunkCreateInfo> pkg(info);
+
+ TUint chunkHandle = DoControl(aCmd, &pkg);
+
+ const TInt r = aPciChunk.SetReturnedHandle(chunkHandle);
+ if(r == KErrNone)
+ {
+ aPciChunk.iPciSize = constPciChunkSize;
+ }
+ return r;
+ }
+
+TUserPciSpace::TUserPciSpace(RPci& aPci)
+ :iPci(&aPci)
+ {}
+
+TUserConfigSpace::TUserConfigSpace(RPci& aPci)
+ :TUserPciSpace(aPci)
+ {}
+
+TUint TUserConfigSpace::Call()
+ {
+ return iPci->AccessConfigSpace(*this);
+ }
+
+TUserPciSpace* TUserConfigSpace::Clone() const
+ {
+ return new TUserConfigSpace(*this);
+ }
+
+TUserMemorySpace::TUserMemorySpace(RPci& aPci, TInt aBarIndex)
+ :TUserPciSpace(aPci), iBarIndex(aBarIndex)
+ {}
+
+TUint TUserMemorySpace::Call()
+ {
+ return iPci->AccessMemorySpace(*this);
+ }
+
+TUserPciSpace* TUserMemorySpace::Clone() const
+ {
+ return new TUserMemorySpace(*this);
+ }
+
+/**
+Test address allocator
+*/
+TInt TestRunPciUnitTest(RPci& pci)
+ {
+ return pci.RunUnitTests();
+ }
+
+
+/**
+Read from a defined address in memory or config space, compare against expected values.
+8,16, and 32 bit accesses performed.
+
+@param aSpace Object gving access to either the config or memory space of a PCI device
+@param aInfo Contains the address and expected value of a dword
+*/
+void TestReadAddressSpace(TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse)
+ {
+ const TUint os = aInfo.iOffset;
+ //Iterate over different widths, and possible
+ //subfields of 32 bit word
+ for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1)
+ {
+ const TInt numberOfFields = (32/bitWidth);
+ for(TInt i=0; i< numberOfFields; i++)
+ {
+ const TInt extraByteOffset = i * (bitWidth >> 3);
+ const TInt byteOffset = os + extraByteOffset;
+ if(aVerbose)
+ test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset);
+
+ const TUint expected = aInfo.Expected(bitWidth, byteOffset);
+ const TUint read = aSpace.Read(bitWidth, byteOffset);
+ if(aVerbose)
+ test.Printf(_L("expect 0x%08x, read 0x%08x\n"), expected, read);
+ test_Equal(expected, read);
+ }
+ }
+ }
+
+/**
+Verify writes and modifications to a defined address in memory or config space. 8,16, and 32 bit
+accesses performed.
+
+@param aSpace Object gving access to either the config or memory space of a PCI device
+@param aInfo Contains the address of a (at least partially) writable dword
+*/
+void TestWriteAddressSpace(TUserPciSpace& aSpace, TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse)
+ {
+ const TUint original = aSpace.Read(32, aInfo.iOffset);
+ const TUint os = aInfo.iOffset;
+ TUint mask = ~aInfo.iReadOnlyMask;
+
+ //The pattern will be truncated when used with bit widths
+ //less than 32.
+ const TUint initPattern = 0xFFFFFFFF;
+
+ for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1)
+ {
+ const TUint pattern = initPattern >> (32-bitWidth);
+ const TInt numberOfFields = (32/bitWidth);
+ for(TInt i=0; i< numberOfFields; i++)
+ {
+ const TInt extraByteOffset = i * (bitWidth >> 3);
+ const TInt byteOffset = os + extraByteOffset;
+ if(aVerbose)
+ test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset);
+ //the full dword we expect
+ //currently assume that the unwritable bits will be 0
+ const TUint writeExpect = (pattern << (bitWidth * i) ) & mask;
+ const TUint clearExpect = 0;
+
+ //do write followed by clear
+ const TUint expect[] = {writeExpect, clearExpect};
+ const TUint write[] = {pattern, 0};
+ for(TInt n = 0; n < 2; n++)
+ {
+ aSpace.Write(bitWidth, byteOffset, write[n]);
+ TUint result = aSpace.Read(32, os);
+
+ if(aVerbose)
+ test.Printf(_L("wrote 0x%08x, expect 0x%08x, read 0x%08x\n"),
+ write[n], expect[n], result);
+ test_Equal(expect[n], result);
+ }
+
+ //test Modify calls. Set then clear pattern
+ TUint set[] = {pattern, 0};
+ TUint clear[] = {0, pattern};
+
+ for(TInt m = 0; m < 2; m++)
+ {
+ aSpace.Modify(bitWidth, byteOffset, clear[m], set[m]);
+ TUint result = aSpace.Read(32, os);
+
+ if(aVerbose)
+ test.Printf(_L("clear 0x%08x, set 0x%08x, expect 0x%08x, read 0x%08x\n"), clear[m], set[m], expect[m], result);
+ test_Equal(expect[m], result);
+ }
+ }
+ }
+
+ //restore orginal value or we will not be able to access device
+ aSpace.Write(32, os, original);
+ }
+
+
+/**
+Verify that a PCI DChunk can be opened and closed from user side
+
+@param pci The RPci object to use
+@param test The RTest object to use
+@param aPciChunkSize The size of the DChunk which would be created
+*/
+void TestOpenAndCloseDChunk(RPci& pci,RTest& test,TInt aPciChunkSize)
+ {
+ RPciChunk testPciDChunk;
+
+ // Create and open Chunk
+ TRequestStatus status;
+ TInt r = pci.OpenPciDChunk(testPciDChunk,aPciChunkSize, &status);
+ test_KErrNone(r);
+
+ test(testPciDChunk.IsWritable());
+ test(testPciDChunk.IsReadable());
+
+ test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciDChunk.Base());
+ test.Printf(_L("PCI Chunk size = %d\n"), testPciDChunk.Size());
+ test.Printf(_L("PCI Address = 0x%08x\n"), testPciDChunk.PciBase());
+
+ //Close Chunk
+ test.Next(_L("Close PCI Chunk handle"));
+
+ RTest::CloseHandleAndWaitForDestruction(testPciDChunk);
+ User::WaitForRequest(status);
+ }
+
+/**
+Verify that a PCI PlatHwChunk can be opened and closed from user side
+
+
+@param pci The RPci object to use
+@param test The RTest object to use
+@param aPciChunkSize The size of the PlatHwChunk which would be created
+*/
+void TestOpenAndClosePciPlatHwChunk(RPci& pci,RTest& test,TInt aPciChunkSize)
+ {
+ RPciChunk testPciPlatHwChunk;
+
+ // Create and open Chunk
+ TRequestStatus status;
+ TInt r = pci.OpenPciPlatHwChunk(testPciPlatHwChunk,aPciChunkSize, &status);
+ test_KErrNone(r);
+
+ test(testPciPlatHwChunk.IsWritable());
+ test(testPciPlatHwChunk.IsReadable());
+
+ test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciPlatHwChunk.Base());
+ test.Printf(_L("PCI Chunk size = %d\n"), testPciPlatHwChunk.Size());
+ test.Printf(_L("PCI Address = 0x%08x\n"), testPciPlatHwChunk.PciBase());
+
+ //Close Chunk
+ testPciPlatHwChunk.Close();
+ User::WaitForRequest(status);
+ test.Next(_L("Closed PCI PlatHwChunk handle"));
+ }
+
+/**
+Verify that pci-mapped DChunk can be opended and closed form user side
+
+@param pci The RPci object to use
+@param test The RTest object to use
+@param aPciChunkSize The size of the pci-mapped DChunk which would be created
+*/
+void TestPciMapppedChunk(RPci& pci,RTest& test,TInt aPciChunkSize)
+ {
+ RPciChunk testPciMappedChunk;
+
+ // Create and open Chunk
+ TRequestStatus status;
+ TInt r = pci.OpenPciMappedChunk(testPciMappedChunk,aPciChunkSize, &status);
+ test_KErrNone(r);
+
+ test(testPciMappedChunk.IsWritable());
+ test(testPciMappedChunk.IsReadable());
+
+ test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciMappedChunk.Base());
+ test.Printf(_L("PCI Chunk size = %d\n"), testPciMappedChunk.Size());
+ test.Printf(_L("PCI Address = 0x%08x\n"), testPciMappedChunk.PciBase());
+
+ //Close Chunk
+ testPciMappedChunk.Close();
+ User::WaitForRequest(status);
+ test.Next(_L("Closed PCI Mapped Chunk handle"));
+ }
+
+/**
+Verify that an RChunk can be open to grant access to the internal PCI window from the user side
+
+@param pci The RPci object to use
+@param test The RTest object to use
+*/
+void TestPciWindowChunk(RPci& pci,RTest& test)
+ {
+ RChunk testPciWindowChunk;
+
+ // Create and open DChunk
+ TInt r = pci.OpenPciWindowChunk(testPciWindowChunk);
+ test_KErrNone(r);
+
+ test(testPciWindowChunk.IsWritable());
+ test(testPciWindowChunk.IsReadable());
+
+ test.Printf(_L("PCI Window Chunk base = 0x%08x\n"), testPciWindowChunk.Base());
+ test.Printf(_L("PCI Window Chunk size = %d\n"), testPciWindowChunk.Size());
+
+ //Close Chunk
+ testPciWindowChunk.Close();
+ test.Next(_L("Closed PCI Window Chunk handle"));
+ }
+
+
+class CPciTest : public CTest
+ {
+protected:
+ CPciTest(const TDesC& aName, TInt aIterations, RPci& aDevice)
+ : CTest(aName, aIterations), iDevice(aDevice)
+ {}
+
+ RPci iDevice;
+ };
+
+/**
+Each instance of test will open a chunk, using the function specified in
+the template argument, FUNC.
+
+The total number of chunks that can be opened by all instances is limited
+by iMaxCount.
+
+All intances of the test will hold their chunk open until iMaxCount has
+been reached.
+*/
+template<ChunkOpenFn FUNC>
+class CPciOpenChunkTest : public CPciTest
+ {
+public:
+ CPciOpenChunkTest(const TDesC& aName, TInt aIterations, RPci& aDevice,
+ RSemaphore aSemOpen, RSemaphore aSemClose, RFastLock aLock, TInt aMaxCount)
+ :CPciTest(aName, aIterations, aDevice),
+ iSemOpen(aSemOpen), iSemClose(aSemClose), iLock(aLock), iMaxCount(aMaxCount)
+ {
+ }
+
+ virtual void RunTest()
+ {
+ RTest test(iName);
+ RPciChunk chunk;
+
+ iSemOpen.Wait();
+ TRequestStatus status;
+ const TInt chunkSize = 0x400;
+ //open chunk by calling FUNC
+ TInt r = ((iDevice).*(FUNC))(chunk, chunkSize, &status);
+ test_KErrNone(r);
+
+ iLock.Wait();
+ iOpenCount++;
+ test.Printf(_L("Opened chunk %d\n"), iOpenCount);
+ if(iOpenCount == iMaxCount)
+ {
+ test.Printf(_L("Opened=%d, max=%d: Allow chunks to close\n"), iOpenCount, iMaxCount);
+ //release all waiting threads
+ //plus 1 preincrement so this
+ //thread also passes
+ iSemClose.Signal(iOpenCount);
+ iOpenCount = 0;
+ }
+ iLock.Signal();
+
+
+ iSemClose.Wait();
+ chunk.Close();
+ User::WaitForRequest(status);
+
+ // permit another chunk to be opened
+ iSemOpen.Signal();
+ test.Close();
+ }
+
+ virtual CTest* Clone() const
+ {
+ //make shallow copy
+ return new CPciOpenChunkTest(*this);
+ }
+
+
+private:
+ RSemaphore& iSemOpen; ///!< Represents the number of available PCI mappings
+ RSemaphore& iSemClose; ///!< Represents the number of threads waiting to close their chunk
+ RFastLock& iLock;
+ static TInt iOpenCount;
+ const TInt iMaxCount;
+ };
+
+template<ChunkOpenFn FUNC>
+TInt CPciOpenChunkTest<FUNC>::iOpenCount = 0;
+
+
+/**
+Test which will perform various reads from a PCI address
+space (config or memory) and confirm that values are read
+as expected
+*/
+class CPciAddressSpaceRead : public CPciTest
+ {
+public:
+ CPciAddressSpaceRead(const TDesC& aName, TInt aIterations, RPci& aDevice,
+ const TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo)
+ :CPciTest(aName, aIterations, aDevice),
+ iAddressSpace(aSpace.Clone()), iSpaceTestInfo(aInfo)
+ {
+ }
+
+ CPciAddressSpaceRead(const CPciAddressSpaceRead& aOther)
+ :CPciTest(aOther)/* TODO-REVIEW have object-sliced aOther - is this ok?*/,
+ iAddressSpace(aOther.iAddressSpace->Clone()), iSpaceTestInfo(aOther.iSpaceTestInfo)
+ {
+ }
+
+ virtual ~CPciAddressSpaceRead()
+ {
+ delete iAddressSpace;
+ }
+
+ virtual void RunTest()
+ {
+ __UHEAP_MARK;
+ RTest test(iName);
+ TestReadAddressSpace(*iAddressSpace, iSpaceTestInfo, test);
+ test.Close();
+ __UHEAP_MARKEND;
+ }
+
+ virtual CTest* Clone() const
+ {
+ //make shallow copy
+ return new CPciAddressSpaceRead(*this);
+ }
+
+private:
+ TUserPciSpace* iAddressSpace;
+ const TPciTestInfo::TAddrSpaceTest& iSpaceTestInfo;
+ };
+
+/**
+For aBuffer, test writing to it then reading back from aWindow
+then write via window and read back from chunk
+
+@param test The RTest object to use
+@param aBuffer RChunk corresponding to a PCI accessible buffer
+@param aWindow RChunk coressponding an appropriate System-to-PCI memory window
+It is presumed to start at PCI address 0
+*/
+void DoLoopBackTest(RTest& test, RPciChunk aBuffer, RChunk aWindow)
+ {
+ test.Start(_L("Test accessing memory via PCI"));
+
+ TUint8* const bufferBase = aBuffer.Base();
+ const TUint bufferSize = aBuffer.Size();
+ const TUint bufferPciBase = aBuffer.PciBase();
+
+ TUint8* const windowBase = aWindow.Base();
+ const TUint windowSize = aWindow.Size();
+
+#define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N))
+ PRINT(bufferBase);
+ PRINT(bufferSize);
+ PRINT(bufferPciBase);
+
+ PRINT(windowBase);
+ PRINT(windowSize);
+
+#undef PRINT
+
+ //need to check that the end of the buffer
+ //is within the windowed region
+ test(bufferPciBase + bufferSize <= windowSize);
+ TUint8* const bufferBaseWithinWindow = windowBase + bufferPciBase;
+
+ test.Next(_L("write chunk"));
+ for(TUint i = 0; i < bufferSize; ++i)
+ {
+ //each byte will hold its own offset modulo 256
+ bufferBase[i] = (TUint8)i;
+ }
+
+ test.Next(_L("read back via window"));
+ for(TUint j=0; j < bufferSize; ++j)
+ {
+ const TUint8 result = bufferBaseWithinWindow[j];
+ test_Equal(j%256, result);
+ }
+
+ //clear chunk
+ memclr(bufferBase, bufferSize);
+ test.Next(_L("write via window"));
+ for(TUint k=0; k < bufferSize; ++k)
+ {
+ //each byte will hold its own offset modulo 256
+ bufferBaseWithinWindow[k] = (TUint8)k;
+ }
+
+ test.Next(_L("read back from chunk"));
+ for(TUint l=0; l < bufferSize; ++l)
+ {
+ const TUint8 result = bufferBase[l];
+ test_Equal(l%256, result);
+ }
+
+ test.End();
+ }
+
+/**
+Take care of opening a chunk, running the test and closing
+*/
+template<ChunkOpenFn OPEN_FUNC>
+inline void LoopBackTest(RPci& aPci, RTest& test, RChunk& aWindow)
+ {
+ RPciChunk pciChunk;
+ const TInt chunkSize = 0x400; //1k
+
+ //call the specified chunk opening function
+ TRequestStatus status;
+ TInt r = ((aPci).*(OPEN_FUNC))(pciChunk, chunkSize, &status);
+ test_KErrNone(r);
+ DoLoopBackTest(test, pciChunk, aWindow);
+ pciChunk.Close();
+ User::WaitForRequest(status);
+ }
+
+/**
+Run the loopback test for the 3 types of buffer supported by the PCI driver.
+DChunk
+DPlatChunk
+Mapped In external memory
+*/
+void TestLoopBack(RPci& aPci, RTest& test)
+ {
+ test.Next(_L("Open PCI window"));
+ RChunk window;
+
+ TInt r = aPci.OpenPciWindowChunk(window);
+ test_KErrNone(r);
+
+ test.Next(_L("DChunk"));
+ LoopBackTest<&RPci::OpenPciDChunk>(aPci, test, window);
+
+ test.Next(_L("DPlatHwChunk"));
+ LoopBackTest<&RPci::OpenPciPlatHwChunk>(aPci, test, window);
+
+ test.Next(_L("DChunk (mapped in)"));
+ LoopBackTest<&RPci::OpenPciMappedChunk>(aPci, test, window);
+
+ window.Close();
+ }
+#ifndef __VC32__ //visual studio 6 doesn't approve of pointer to member function template parameters
+/**
+Run the CPciOpenChunkTest for each type of chunk. This function also creates (and destroys) the
+necessary semaphores and locks.
+CPciOpenChunkTest objects are run in multiple threads using MultipleTestRun().
+
+@param aDevice Handle to the test driver
+@param test RTest to use.
+@param aBufferLimit The maximum number of buffers which can be opened simultaneously
+*/
+void TestBufferOpenConcurrency(RPci& aDevice, RTest& test, TInt aBufferLimit)
+ {
+ RSemaphore semaphoreOpen;
+ RSemaphore semaphoreClose;
+ RFastLock lock;
+
+ TInt r = semaphoreOpen.CreateLocal(aBufferLimit);
+ test_KErrNone(r);
+
+ r = semaphoreClose.CreateLocal(0);
+ test_KErrNone(r);
+
+ r = lock.CreateLocal();
+ test_KErrNone(r);
+
+ const TInt iterations = 3;
+ {
+ test.Printf(_L("Opening %d PCI DChunks in %d threads\n"), aBufferLimit, aBufferLimit);
+ CPciOpenChunkTest<&RPci::OpenPciDChunk>
+ dChunkTest(_L("Concurrent-DChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit);
+
+ MultipleTestRun(test, dChunkTest, aBufferLimit);
+ }
+
+ {
+ test.Printf(_L("Opening %d PCI DPlatHwChunks in %d threads\n"), aBufferLimit, aBufferLimit);
+ CPciOpenChunkTest<&RPci::OpenPciPlatHwChunk>
+ platChunkTest(_L("Concurrent-DPlatHwChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit);
+
+ MultipleTestRun(test, platChunkTest, aBufferLimit);
+ }
+
+ {
+ test.Printf(_L("Opening %d PCI Mapped chunks in %d threads\n"), aBufferLimit, aBufferLimit);
+ CPciOpenChunkTest<&RPci::OpenPciMappedChunk>
+ mappedChunkTest(_L("Concurrent-DChunk(mapped)"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit);
+
+ MultipleTestRun(test, mappedChunkTest, aBufferLimit);
+ }
+
+ semaphoreOpen.Close();
+ semaphoreClose.Close();
+ lock.Close();
+ }
+#endif
+
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ _LIT(KPci, "PCI");
+ RTest test(KPci);
+ test.Start(_L("Running PCI tests\n"));
+
+ TInt r = User::LoadLogicalDevice(KPciLdd);
+
+ __KHEAP_MARK;
+
+ if(r==KErrNotFound)
+ {
+ test.Printf(_L("No PCI system present - skipping test\n"));
+ return KErrNone;
+ }
+ if(r!=KErrNone && r!=KErrAlreadyExists)
+ {
+ test_KErrNone(r);
+ }
+
+ test.Next(_L("Open non-existant device\n"));
+ RPci device;
+ TPciDevice unavailable;
+ r = device.Open(unavailable);
+ test_Equal(KErrNotFound, r);
+
+ RPci pciInfo;
+ r = pciInfo.Open();
+ test_KErrNone(r);
+
+ test.Next(_L("Get test info from driver\n"));
+ TPciTestInfo info;
+ r = pciInfo.GetTestInfo(info);
+ test_KErrNone(r);
+ pciInfo.Close();
+
+ test.Next(_L("Open test device\n"));
+ r = device.Open(info.iDevice);
+ test_KErrNone(r);
+
+ test.Next(_L("Run Device Unit Test\n"));
+ r=TestRunPciUnitTest(device);
+ test_KErrNone(r);
+
+ test.Next(_L("Read config space\n"));
+ TUserConfigSpace cs(device);
+ TestReadAddressSpace(cs, info.iCfgSpaceRead, test);
+
+ test.Next(_L("Write config space\n"));
+ TestWriteAddressSpace(cs, info.iCfgSpaceWrite, test);
+
+ test.Next(_L("Read memory space\n"));
+ TUserMemorySpace ms(device, info.iMemSpaceIndex);
+ TestReadAddressSpace(ms, info.iMemSpaceRead, test);
+
+ test.Next(_L("Modify memory space\n"));
+ TestWriteAddressSpace(ms, info.iMemSpaceWrite, test);
+
+ {
+ const TInt addrSpaceThreadCount = 4;
+ const TInt iterations = 100;
+ test.Next(_L("Concurrent config space reads"));
+ CPciAddressSpaceRead cfgSpaceRead(_L("Cfg Space Read"), iterations, device, cs, info.iCfgSpaceRead);
+ MultipleTestRun(test, cfgSpaceRead, addrSpaceThreadCount);
+
+ test.Next(_L("Concurrent memory space reads"));
+ CPciAddressSpaceRead memSpaceRead(_L("Memory Space Read"), iterations, device, ms, info.iMemSpaceRead);
+ MultipleTestRun(test, memSpaceRead, addrSpaceThreadCount);
+ }
+
+ TInt testDChunkSize = 0x4000;
+ test.Next(_L("Open and Close DChunks\n"));
+ TestOpenAndCloseDChunk(device,test,testDChunkSize);
+
+ TInt testDPlatChunkSize = 0x2000;
+ test.Next(_L("Open and Close PlatHwChunks\n"));
+ TestOpenAndClosePciPlatHwChunk(device,test,testDPlatChunkSize);
+
+ //TestPciMapppedChunk() fails for sizes greater than 4K.
+ //The issue is that a block of externally mapped memory must be
+ //naturally alligned in order to be accessible to the PCI bus (ie
+ //an 8k buffer would have to start at an address which is a
+ //multiple of 8k.
+ //
+ //Now we could fix this for sure on the kernel side, by making
+ //sure we only commit correctly aligned memory into the chunk (as
+ //the pci driver itself does),
+ //However, by using a 4k chunk, we know this will be on a page
+ //boundary so the alignment is correct (assuming the page size
+ //isn't changed).
+ TInt testMapppedChunkSize = 0x1000;
+ test.Next(_L("Open and Close Pci Mappped Chunk\n"));
+ TestPciMapppedChunk(device,test,testMapppedChunkSize);
+
+ test.Next(_L("Open and Close Pci Window Chunk\n"));
+ TestPciWindowChunk(device,test);
+
+ const TInt numberOfThreads = info.iNumberOfBars;
+ test.Printf(_L("Open buffers concurrently, max supported = %d\n"), numberOfThreads);
+#ifndef __VC32__
+ TestBufferOpenConcurrency(device, test, numberOfThreads);
+#else
+ test.Printf(_L("TestBufferOpenConcurrency not implemented for WINS"), numberOfThreads);
+#endif
+
+ test.Next(_L("Test loop back"));
+ TestLoopBack(device, test);
+
+ device.Close();
+ __KHEAP_MARKEND;
+
+ r = User::FreeLogicalDevice(KPciLdd);
+ test_KErrNone(r);
+
+ test.End();
+ test.Close();
+
+ __UHEAP_MARKEND;
+ return KErrNone;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pci/t_pci.h Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,254 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description: This is the header file for the PCI driver test , so far implemented
+// only on the Naviengine platform
+
+#ifndef __TPCI_TEST_H
+#define __TPCI_TEST_H
+
+#ifndef __KERNEL_MODE__
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+ #include <e32def_private.h>
+#endif // __KERNEL_MODE__
+
+_LIT(KPciLdd, "d_pci.ldd");
+_LIT(KPciLddFactory, "PCI_test_factory");
+_LIT(KPciTest, "PCI Test LDD");
+
+/**
+Test driver op-codes
+*/
+enum TPciTestCmd
+ {
+ EGetTestInfo,
+ EAccessConfigSpace,
+ EAccessMemorySpace,
+ EOpenPciDChunk,
+ EOpenPciPlatHwChunk,
+ EOpenPciMappedChunk,
+ EOpenPciWindowChunk,
+ ERunUnitTests
+ };
+
+/**
+Identifies a PCI Function (device) on the system
+*/
+struct TPciDevice
+ {
+ TPciDevice()
+ :iVendorId(0xFFFFFFFF), iDeviceId(0xFFFFFFFF), iInstance(0) {}
+
+ TPciDevice(TUint aVendorId, TUint aDeviceId, TInt aInstance=0)
+ :iVendorId(aVendorId), iDeviceId(aDeviceId), iInstance(aInstance) {}
+
+ TUint iVendorId;
+ TUint iDeviceId;
+ TInt iInstance; ///< Unit to open (there could be multiple devices on system)
+ };
+
+/**
+Used to send chunk size and recieve
+PCI address
+*/
+struct TPciChunkCreateInfo
+ {
+ TPciChunkCreateInfo()
+ :iSize(0), iPciAddress(NULL)
+ {
+ }
+
+ TPciChunkCreateInfo(TInt aSize, TUint& aPciAddress, TRequestStatus* aStatus=NULL)
+ :iSize(aSize), iPciAddress(&aPciAddress), iStatus(aStatus)
+ {
+ }
+ TInt iSize;
+ TUint* iPciAddress;
+ TRequestStatus* iStatus;
+ };
+
+/**
+Information about the PSL required by the
+user side test
+*/
+struct TPciTestInfo
+ {
+ TPciDevice iDevice; ///< Probe for this
+
+ /**
+ Supplies the necessary information to test Read, Write, and
+ Modify for a word of PCI memory or configuration space
+ */
+ struct TAddrSpaceTest
+ {
+ TAddrSpaceTest()
+ :iOffset(0), iExpectedValue(0), iReadOnlyMask(0)
+ {}
+
+ TAddrSpaceTest(TUint aOffset, TUint aExpectedValue, TUint aReadOnlyMask)
+ :iOffset(aOffset), iExpectedValue(aExpectedValue), iReadOnlyMask(aReadOnlyMask)
+ {}
+
+ /**
+ Returns a specified sub byte, or word from the whole dword
+ */
+ inline TUint Expected(TInt aBitWidth, TInt aExtraOffset) const
+ {
+ //the right shift required to get field to bit 0
+ const TInt shift = 8 *((aExtraOffset + iOffset) % 4);
+
+ const TUint mask = 0xFFFFFFFF >> (32-aBitWidth);
+ return (iExpectedValue >> shift) & mask;
+ }
+
+ const TUint iOffset;
+ const TUint iExpectedValue; ///< The initial value of word
+ const TUint iReadOnlyMask; ///< Mask of unwritable bits
+ //Future work, memory spaces should state a bar index
+ };
+
+
+ TAddrSpaceTest iCfgSpaceRead;
+ TAddrSpaceTest iCfgSpaceWrite;
+
+ TUint iMemSpaceIndex; ///< Memory space to select
+ TAddrSpaceTest iMemSpaceRead;
+ TAddrSpaceTest iMemSpaceWrite;
+
+ TInt iNumberOfBars; ///< Number of simultaneous mappings into PCI space
+ };
+
+class RPci;
+class TAddrSpace;
+/**
+This class encapsulates all the various read/write/and modify commands
+that can be carried out on a PCI memory space. The command is stored user
+side, and then executed on kernel side when KRun() is called.
+*/
+class TUserPciSpace
+ {
+public:
+ TUserPciSpace()
+ :iPci(NULL), iOperation(EInvalid), iBitWidth(0), iOffset(0),
+ iWriteValue(0), iClearMask(0), iSetMask(0)
+ {}
+ TUserPciSpace(RPci& aPci);
+
+ /**
+ Perform the encapsulated read/write/or modify
+ @note Only run on kernel side
+ */
+ TUint KRun(TAddrSpace& aAddrSpace);
+
+ /**
+ Clone method is required so that multiple threads may
+ have their own copy of a TUserPciSpace (without knowing
+ its runtime type)
+ */
+ virtual TUserPciSpace* Clone() const = 0;
+
+ TUint Read(TInt aBitWidth, TUint aOffset)
+ {
+ iOffset = aOffset;
+ iOperation = ERead;
+ iBitWidth = aBitWidth;
+
+ return Call();
+ }
+
+ void Write(TInt aBitWidth, TUint aOffset, TUint aValue)
+ {
+ iOffset = aOffset;
+ iOperation = EWrite;
+ iBitWidth = aBitWidth;
+
+ iWriteValue = aValue;
+ Call();
+ }
+
+ void Modify(TInt aBitWidth, TUint aOffset, TUint aClearMask, TUint aSetMask)
+ {
+ iOffset = aOffset;
+ iOperation = EModify;
+ iBitWidth = aBitWidth;
+
+ iClearMask = aClearMask;
+ iSetMask = aSetMask;
+ Call();
+ }
+
+protected:
+ /**
+ Makes a request to iPci and passes a copy of this object to
+ the kernel side.
+ */
+ virtual TUint Call() =0;
+
+ enum TOperation {EInvalid, ERead, EWrite, EModify};
+
+ /**
+ Pointer to a PCI device handle
+ */
+ RPci* iPci;
+
+ TOperation iOperation; //!< Type of access to perform
+ TInt iBitWidth;
+
+ TUint iOffset;
+ TUint32 iWriteValue;
+ TUint32 iClearMask;
+ TUint32 iSetMask;
+ };
+
+/**
+Grants access to a PCI device's (identified
+by aPci) config space from user side
+*/
+class TUserConfigSpace : public TUserPciSpace
+ {
+public:
+ TUserConfigSpace()
+ :TUserPciSpace()
+ {}
+ TUserConfigSpace(RPci& aPci);
+
+ virtual TUserPciSpace* Clone() const;
+private:
+ TUint Call();
+ };
+
+/**
+Grants access to some region of a PCI
+device's memory space. A PCI device(or function)
+may have up to 8 distinct memory spaces
+*/
+class TUserMemorySpace : public TUserPciSpace
+ {
+public:
+ TUserMemorySpace()
+ :TUserPciSpace(), iBarIndex(-1)
+ {}
+
+ TUserMemorySpace(RPci& aPci, TInt aBarIndex);
+
+ virtual TUserPciSpace* Clone() const;
+
+ inline TInt BarIndex() {return iBarIndex;}
+
+private:
+ TUint Call();
+
+ TInt iBarIndex; ///< Each PCI function may have up to 8 memory spaces
+ };
+
+#endif //__TPCI_TEST_H
--- a/kerneltest/e32test/resourceman/dynamicresource.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/resourceman/dynamicresource.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -34,27 +34,21 @@
DMLIGLSSHNDynamicResource::DMLIGLSSHNDynamicResource() : DDynamicPowerResource(KDMLIGLSSHNDynamicResource, -5), iMinLevel(-5), iMaxLevel(-10), iCurrentLevel(-5)
{
iFlags = KMultiLevel | KLongLatencySet | KShared | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBLGLSSHNDynamicResource, "DynamicResource3");
DBLGLSSHNDynamicResource::DBLGLSSHNDynamicResource() : DDynamicPowerResource(KDBLGLSSHNDynamicResource, 1), iMinLevel(1), iMaxLevel(0), iCurrentLevel(1)
{
iFlags = KBinary | KLongLatencySet | KLongLatencyGet | KShared | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLLGLSSHPDynamicResource, "DynamicResource4");
DMLLGLSSHPDynamicResource::DMLLGLSSHPDynamicResource() : DDynamicPowerResource(KDMLLGLSSHPDynamicResource, 10), iMinLevel(10), iMaxLevel(20), iCurrentLevel(10)
{
iFlags = KMultiLevel | KLongLatencySet | KLongLatencyGet | KShared;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
//Constructors for dynamic dependent resources
@@ -63,36 +57,28 @@
{
// Make it a Instantaneous Resource.
iFlags = KMultiLevel;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDDynamicResourceD02, "DynamicDependResourceDI");
DDynamicResourceD02::DDynamicResourceD02() : DDynamicPowerResourceD(KDDynamicResourceD02, 0), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
{
iFlags = KBinary | KLongLatencySet | KLongLatencyGet | KShared;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDDynamicResourceD03, "DynamicDependResourceDJ");
DDynamicResourceD03::DDynamicResourceD03() : DDynamicPowerResourceD(KDDynamicResourceD03, 19), iMinLevel(19), iMaxLevel(9), iCurrentLevel(19)
{
iFlags = KMultiLevel | KLongLatencySet | KShared | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDDynamicResourceD04, "DynamicDependResourceDK");
DDynamicResourceD04::DDynamicResourceD04() : DDynamicPowerResourceD(KDDynamicResourceD04, 0), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
{
iFlags = KBinary | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
//Get info implementation for dynamic resources
--- a/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_extended_psl.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_extended_psl.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -141,27 +141,21 @@
DMLSLGLSPDependResource::DMLSLGLSPDependResource() : DStaticPowerResourceD(KDMLSLGLSPDependResource, -100), iMinLevel(-100), iMaxLevel(100), iCurrentLevel(-100)
{
iFlags = KMultiLevel | KLongLatencyGet | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSIGLSNDependResource, "StaticDependResourceA");
DMLSIGLSNDependResource::DMLSIGLSNDependResource() : DStaticPowerResourceD(KDMLSIGLSNDependResource, -10), iMinLevel(-10), iMaxLevel(-20), iCurrentLevel(-10)
{
iFlags = KMultiLevel | KLongLatencySet | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSIGLSPDependResource, "StaticDependResourceF");
DBSIGLSPDependResource::DBSIGLSPDependResource() : DStaticPowerResourceD(KDBSIGLSPDependResource, 0), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
{
iFlags = KBinary | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHIGLSPDependResource, "StaticDependResourceE");
@@ -169,36 +163,28 @@
{
// Make it a Instantaneous Resource.
iFlags = KMultiLevel | KShared;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSHLGLSNDependResource, "StaticDependResourceC");
DBSHLGLSNDependResource::DBSHLGLSNDependResource() : DStaticPowerResourceD(KDBSHLGLSNDependResource, 1), iMinLevel(1), iMaxLevel(0), iCurrentLevel(1)
{
iFlags = KBinary | KLongLatencyGet | KLongLatencySet | KShared | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHLGLSNDependResource, "StaticDependResourceG");
DMLSHLGLSNDependResource::DMLSHLGLSNDependResource() : DStaticPowerResourceD(KDMLSHLGLSNDependResource, 75), iMinLevel(75), iMaxLevel(30), iCurrentLevel(75)
{
iFlags = KMultiLevel | KLongLatencyGet | KLongLatencySet | KShared | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHLGLSCDependResource, "DMLSHLGLSCDependResource");
DMLSHLGLSCDependResource::DMLSHLGLSCDependResource() : DStaticPowerResourceD(KDMLSHLGLSCDependResource, -100), iMinLevel(-100), iMaxLevel(100), iCurrentLevel(-100)
{
iFlags = KMultiLevel;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
//Implementation of handle dependent state for all resources
--- a/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_psl.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_psl.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -456,45 +456,35 @@
DMLSLGLSPResource::DMLSLGLSPResource() : DStaticPowerResource(KDMLSLGLSPResource, 75), iMinLevel(10), iMaxLevel(75), iCurrentLevel(75), iPolled(EFalse)
{
iFlags = KMultiLevel | KLongLatencySet | KLongLatencyGet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSLGISNResource, "DBSLGISNResource");
DBSLGISNResource::DBSLGISNResource() : DStaticPowerResource(KDBSLGISNResource, E_ON), iMinLevel(E_ON), iMaxLevel(E_OFF), iCurrentLevel(E_ON), iPolled(ETrue)
{
iFlags = KLongLatencyGet | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSLGISNResource, "DMLSLGISNResource");
DMLSLGISNResource::DMLSLGISNResource() : DStaticPowerResource(KDMLSLGISNResource, 75), iMinLevel(75), iMaxLevel(10), iCurrentLevel(75), iPolled(EFalse)
{
iFlags = KMultiLevel | KLongLatencyGet | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSIGLSPResource, "DBSIGLSPResource");
DBSIGLSPResource::DBSIGLSPResource() : DStaticPowerResource(KDBSIGLSPResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue)
{
iFlags = KBinary | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSIGLSPResource, "DMLSIGLSPResource");
DMLSIGLSPResource::DMLSIGLSPResource() : DStaticPowerResource(KDMLSIGLSPResource, 75), iMinLevel(10), iMaxLevel(100), iCurrentLevel(75), iPolled(EFalse)
{
iFlags = KMultiLevel | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSHIGISPResource, "DBSHIGISPResource");
@@ -525,54 +515,42 @@
DBSHLGLSPResource::DBSHLGLSPResource() : DStaticPowerResource(KDBSHLGLSPResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue)
{
iFlags = KBinary | KShared | KLongLatencySet | KLongLatencyGet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHLGLSPResource, "DMLSHLGLSPResource");
DMLSHLGLSPResource::DMLSHLGLSPResource() : DStaticPowerResource(KDMLSHLGLSPResource, 70), iMinLevel(5), iMaxLevel(70), iCurrentLevel(70), iPolled(EFalse)
{
iFlags = KMultiLevel | KShared | KLongLatencySet | KLongLatencyGet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSHLGISNResource, "DBSHLGISNResource");
DBSHLGISNResource::DBSHLGISNResource() : DStaticPowerResource(KDBSHLGISNResource, E_ON), iMinLevel(E_ON), iMaxLevel(E_OFF), iCurrentLevel(E_ON), iPolled(ETrue)
{
iFlags = KBinary | KShared | KLongLatencyGet | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHLGISNResource, "DMLSHLGISNResource");
DMLSHLGISNResource::DMLSHLGISNResource() : DStaticPowerResource(KDMLSHLGISNResource, 75), iMinLevel(75), iMaxLevel(10), iCurrentLevel(75), iPolled(EFalse)
{
iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseNegative;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSHIGLSPResource, "DBSHIGLSPResource");
DBSHIGLSPResource::DBSHIGLSPResource() : DStaticPowerResource(KDBSHIGLSPResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue)
{
iFlags = KBinary | KShared | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDMLSHIGLSPResource, "DMLSHIGLSPResource");
DMLSHIGLSPResource::DMLSHIGLSPResource() : DStaticPowerResource(KDMLSHIGLSPResource, 75), iMinLevel(10), iMaxLevel(75), iCurrentLevel(75), iPolled(EFalse)
{
iFlags = KMultiLevel | KShared | KLongLatencySet;
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
_LIT(KDBSHLGLSCResource, "KDBSHLGLSCResource");
@@ -580,9 +558,7 @@
{
iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseCustom;
SetCustomFunction(CustomFunction);
- NKern::LockSystem();
iBlockTime = MIN_BLOCK_TIME + Kern::Random() % MAX_BLOCK_TIME;
- NKern::UnlockSystem();
}
//DoRequest implementation of all functions
--- a/kerneltest/e32test/system/d_dobject.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/system/d_dobject.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -665,10 +665,10 @@
// Bit 30 thread local flag (ignored)
// Bit 31 special handle flag (should be 0)
//
- NKern::LockSystem();
TInt randomHandle = Kern::Random() & 0x3fff7fff;
TInt uniqueID = 0; // any object type!
-
+
+ NKern::LockSystem();
object = myIx.At(randomHandle, uniqueID);
NKern::UnlockSystem();
--- a/kerneltest/e32test/usb/t_usb_device/include/activecontrol.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/include/activecontrol.h Sun Mar 14 13:15:32 2010 +0000
@@ -80,7 +80,10 @@
TInt ReEnumerate();
TInt ProcessEp0ControlPacket();
void PrintHostLog();
-
+
+ void FillEndpointsResourceAllocation(IFConfigPtr aIfCfg);
+ void PopulateInterfaceResourceAllocation(IFConfigPtr aFirstIfCfg, TInt aPortNumber);
+
private:
CConsoleBase* iConsole; // a console to read from
CActiveStallNotifier* iStallNotifier[KMaxInterfaces];
@@ -91,6 +94,7 @@
TInt iNumInterfaceSettings[KMaxInterfaces];
TInt iTotalChannels;
TBool iSoftwareConnect;
+ TBool iSupportResourceAllocationV2;
TBool iHighSpeed;
RFs iFs;
RFile iConfigFile;
--- a/kerneltest/e32test/usb/t_usb_device/src/activecontrol.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/src/activecontrol.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -127,6 +127,7 @@
: CActive(EPriorityNormal),
iConsole(aConsole),
iSoftwareConnect(EFalse),
+ iSupportResourceAllocationV2(EFalse),
iHighSpeed(EFalse),
iConfigFileName(aConfigFile),
iScriptFileName(aScriptFile),
@@ -219,7 +220,12 @@
}
test_NotNull(ifPtr);
-
+
+ if (iSupportResourceAllocationV2)
+ {
+ PopulateInterfaceResourceAllocation(ifPtr, portNumber);
+ }
+
IFConfigPtr defaultIfPtr = ifPtr;
SetupInterface(&ifPtr,portNumber);
@@ -228,15 +234,17 @@
test_KErrNone(iPort[portNumber].FinalizeInterface(tChunk));
#endif
- // allocate endpoint DMA and double buffering for all endpoints on default interface
- for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+ if (!iSupportResourceAllocationV2)
{
- defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
- #ifndef USB_SC
- defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
- #endif
- }
-
+ // allocate endpoint DMA and double buffering for all endpoints on default interface when using resource allocation v1 api
+ for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+ {
+ defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
+ #ifndef USB_SC
+ defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
+ #endif
+ }
+ }
}
iTotalChannels += lddPtr->iNumChannels;
@@ -369,14 +377,17 @@
RChunk *tChunk = &gChunk;
test_KErrNone(iPort[portNumber].FinalizeInterface(tChunk));
#endif
-
- // allocate endpoint DMA and double buffering for all endpoints on default interface
- for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+
+ if (!iSupportResourceAllocationV2)
{
- defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
- #ifndef USB_SC
- defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
- #endif
+ // allocate endpoint DMA and double buffering for all endpoints on default interface with resource allocation v1 api
+ for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+ {
+ defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
+ #ifndef USB_SC
+ defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
+ #endif
+ }
}
}
@@ -422,6 +433,59 @@
test.End();
}
+
+void CActiveControl::FillEndpointsResourceAllocation(IFConfigPtr aIfCfg)
+ {
+
+ #ifdef USB_SC
+ TUsbcScInterfaceInfo* iInfoPtr = aIfCfg->iInfoPtr;
+ #else
+ TUsbcInterfaceInfo* iInfoPtr = aIfCfg->iInfoPtr;
+ #endif
+
+ // fill resource allocation info in the endpoint info with resource allocation v2
+ for (TUint8 i = 1; i <= iInfoPtr->iTotalEndpointsUsed; i++)
+ {
+ if (aIfCfg->iEpDMA[i-1])
+ {
+ iInfoPtr->iEndpointData[i-1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DMA;
+ }
+ else
+ {
+ iInfoPtr->iEndpointData[i-1].iFeatureWord1 &= (~KUsbcEndpointInfoFeatureWord1_DMA);
+ }
+ #ifndef USB_SC
+ if (aIfCfg->iEpDoubleBuff[i-1])
+ {
+ iInfoPtr->iEndpointData[i-1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+ }
+ else
+ {
+ iInfoPtr->iEndpointData[i-1].iFeatureWord1 &= (~KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
+ }
+ #endif
+ }
+ }
+
+// all alternative settings of the interface 'aFirstIfCfg' will be populated
+void CActiveControl::PopulateInterfaceResourceAllocation(IFConfigPtr aFirstIfCfg, TInt aPortNumber)
+ {
+ FillEndpointsResourceAllocation(aFirstIfCfg);
+
+ IFConfigPtr ifCfgPtr = aFirstIfCfg->iPtrNext;
+ while (ifCfgPtr != NULL)
+ {
+ if (ifCfgPtr->iAlternateSetting)
+ {
+ FillEndpointsResourceAllocation(ifCfgPtr);
+ ifCfgPtr = ifCfgPtr->iPtrNext;
+ }
+ else
+ {
+ ifCfgPtr = NULL;
+ }
+ }
+ }
void CActiveControl::SetupInterface(IFConfigPtr* aIfPtr, TInt aPortNumber)
{
@@ -1397,11 +1461,16 @@
TUSB_PRINT1("Supports unpowered cable detection: %s\n",
(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
_S("yes") : _S("no"));
+ TUSB_PRINT1("Supports endpoint resource allocation v2 scheme: %s\n",
+ (d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) ?
+ _S("yes") : _S("no"));
TUSB_PRINT("");
iSoftwareConnect = d_caps().iConnect; // we need to remember this
test_Equal(aLddPtr->iSoftConnect,iSoftwareConnect);
+ iSupportResourceAllocationV2 = ((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
+
// only check capabilities if set; therefore allowing them to be disabled
if (aLddPtr->iSelfPower)
{
--- a/kerneltest/e32test/usb/t_usb_device/src/activedevicestatenotifier.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/src/activedevicestatenotifier.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -114,28 +114,35 @@
TUint8 altSetting = iDeviceState & ~KUsbAlternateSetting;
TUSB_PRINT2("Device State notifier: Alternate interface %d setting has changed: now %d",
iPortNumber, altSetting);
-
- // allocate endpoint DMA and double buffering for all endpoints on interface
- for (TUint8 ifNumber = 0; ifNumber < 128; ifNumber++)
+
+ TUsbDeviceCaps dCaps;
+ iPort->DeviceCaps(dCaps);
+ TBool isResourceAllocationV2 = ((dCaps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
+ if (!isResourceAllocationV2)
{
- IFConfigPtr newIfPtr = gInterfaceConfig[ifNumber][altSetting];
- if (newIfPtr)
+ // allocate endpoint DMA and double buffering for all endpoints on interface for resource allocation v1
+ // if resource allocation v2, refer to CActiveControl::ConstructL and CActiveControl::PopulateInterfaceResourceAllocation
+ for (TUint8 ifNumber = 0; ifNumber < 128; ifNumber++)
{
- if (newIfPtr->iPortNumber == iPortNumber)
+ IFConfigPtr newIfPtr = gInterfaceConfig[ifNumber][altSetting];
+ if (newIfPtr)
{
- // allocate endpoint DMA and double buffering for all endpoints on default interface
- for (TUint8 i = 1; i <= newIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+ if (newIfPtr->iPortNumber == iPortNumber)
{
- newIfPtr->iEpDMA[i-1] ? gActiveControl->AllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i);
- #ifndef USB_SC
- newIfPtr->iEpDoubleBuff[i-1] ? gActiveControl->AllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i);
- #endif
+ // allocate endpoint DMA and double buffering for all endpoints on default interface
+ for (TUint8 i = 1; i <= newIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
+ {
+ newIfPtr->iEpDMA[i-1] ? gActiveControl->AllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateEndpointDMA(iPort,(TENDPOINTNUMBER)i);
+ #ifndef USB_SC
+ newIfPtr->iEpDoubleBuff[i-1] ? gActiveControl->AllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i) : gActiveControl->DeAllocateDoubleBuffering(iPort,(TENDPOINTNUMBER)i);
+ #endif
+ }
+ break;
}
- break;
}
}
- }
-
+ }
+
if (gAltSettingOnNotify)
{
for (TUint16 i =0; i < KMaxConcurrentTests; i++)
--- a/kerneltest/e32test/usbho/t_usbdi/inc/PBASE-T_USBDI-1231.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/usbho/t_usbdi/inc/PBASE-T_USBDI-1231.h Sun Mar 14 13:15:32 2010 +0000
@@ -130,7 +130,10 @@
TCaseSteps iCaseStep;
TThreadPriority iPriority;
-
+
+public:
+ TBool iInterface0Resumed;
+
private:
/**
The functor for this test case for the factory
--- a/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1231.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1231.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -40,7 +40,7 @@
}
CUT_PBASE_T_USBDI_1231::CUT_PBASE_T_USBDI_1231(TBool aHostRole) :
- CBaseTestCase(KTestCaseId, aHostRole)
+ CBaseTestCase(KTestCaseId, aHostRole), iInterface0Resumed(EFalse)
{
}
@@ -148,7 +148,9 @@
LOG_FUNC
RDebug::Printf("====> DeviceInsertedL entry priority = %d", RThread().Priority());
-
+
+ iInterface0Resumed = EFalse;
+
Cancel(); // Cancel the timer
TInt err(KErrNone);
iDeviceHandle = aDeviceHandle;
@@ -244,6 +246,7 @@
TInt testStep = self->iCaseStep;
RDebug::Printf(" -watcher 0 iStatus = %d <teststep %d>",completionCode, testStep);
+ self->iInterface0Resumed = ETrue;
switch (self->iCaseStep)
{
@@ -339,8 +342,15 @@
if (aNewState == RUsbDevice::EDeviceActive)
{
RDebug::Printf("Device resume!");
- iCaseStep = EValidResumeWhenSuspending;
-
+ if (!iInterface0Resumed)
+ {
+ iCaseStep = EValidResumeWhenSuspending;
+ }
+ else
+ {
+ iCaseStep = EPassed;
+ SendEp0Request();
+ }
}
else
{
--- a/kerneltest/e32utils/group/bld.inf Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/e32utils/group/bld.inf Sun Mar 14 13:15:32 2010 +0000
@@ -35,8 +35,6 @@
../profiler/profiler.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(profiler.h)
-../analyse/profiler.rtf /epoc32/engdoc/profiler/profiler.rtf
-
../d_exc/printstk.pl /epoc32/rom/tools/printstk.pl
../d_exc/printsym.pl /epoc32/rom/tools/printsym.pl
@@ -53,6 +51,9 @@
btrace_host
#endif
+//Nist statistical test suite for Secure RNG in kernel
+nistsecurerng
+
PRJ_MMPFILES
#if defined(TOOLS2)
@@ -99,7 +100,6 @@
#ifndef SMP
../d_exc/d_exc
-../sdpartition/sdpartition
#endif
../d_exc/minkda
@@ -115,3 +115,4 @@
#endif // !TOOLS
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32utils/group/nistsecurerng.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -0,0 +1,62 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+TARGET nistsecurerng.exe
+TARGETTYPE exe
+UID 0x20027F9A
+
+USERINCLUDE ../nistsecurerng/include
+USERINCLUDE ../nistsecurerng/include/utils
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH ../nistsecurerng/src
+SOURCE assess.cpp
+SOURCE approximateEntropy.cpp
+SOURCE blockFrequency.cpp
+SOURCE cephes.cpp
+SOURCE cusum.cpp
+SOURCE discreteFourierTransform.cpp
+SOURCE dfft.cpp
+SOURCE frequency.cpp
+SOURCE generators.cpp
+SOURCE genutils.cpp
+SOURCE linearComplexity.cpp
+SOURCE longestRunOfOnes.cpp
+SOURCE matrix.cpp
+SOURCE nonOverlappingTemplateMatchings.cpp
+SOURCE overlappingTemplateMatchings.cpp
+SOURCE randomExcursions.cpp
+SOURCE randomExcursionsVariant.cpp
+SOURCE rank.cpp
+SOURCE runs.cpp
+SOURCE serial.cpp
+SOURCE universal.cpp
+SOURCE utilities.cpp
+//provides some openc c functions that are not avaiable in kernel
+
+SOURCEPATH ../nistsecurerng/src/utils
+SOURCE openc.cpp
+SOURCE qsort.cpp
+
+SOURCEPATH ../nistsecurerng/src/math
+SOURCE erf.cpp
+
+
+LIBRARY euser.lib efsrv.lib
+
+EPOCHEAPSIZE 0x0800000 0x8000000
+
+SMPSAFE
--- a/kerneltest/f32test/demandpaging/t_wdpstress.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/demandpaging/t_wdpstress.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1793,7 +1793,10 @@
//infoPtrs[index]->SetUseHeap(gThreadHeap);
ret = pTheThreads[index].Create(*infoPtrs[index]);
if (ret != KErrNone)
+ {
+ pThreadInUse[index] = 0;
continue;
+ }
pTheThreads[index].Resume();
pThreadInUse[index] = 1;
continue;
--- a/kerneltest/f32test/fileshare/handshare.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/fileshare/handshare.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -648,7 +648,7 @@
TInt end_thc, end_phc;
RThread().HandleCount(end_phc, end_thc);
test(start_thc == end_thc);
- test(start_phc == end_phc);
+// test(start_phc == end_phc);
// and also for pending requests ...
test(RThread().RequestCount() == 0);
@@ -699,7 +699,7 @@
// wait for server2's thread to end gracefully
User::WaitForRequest(statq);
-
+ test(statq == KErrNone);
server2Thread.Close();
--- a/kerneltest/f32test/filesystem/automounter/t_automounter.mmp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/filesystem/automounter/t_automounter.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -25,7 +25,9 @@
SOURCE fat_utils.cpp f32_test_utils.cpp
LIBRARY euser.lib efsrv.lib hal.lib
-SYSTEMINCLUDE /epoc32/include
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
USERINCLUDE ../../fileutils/inc
USERINCLUDE ../fat
--- a/kerneltest/f32test/group/b_gen.mmp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/group/b_gen.mmp Sun Mar 14 13:15:32 2010 +0000
@@ -22,8 +22,11 @@
SOURCE t_main.cpp
SOURCEPATH ../fileutils/src
SOURCE t_chlffs.cpp
+SOURCE f32_test_utils.cpp
+
LIBRARY euser.lib efsrv.lib hal.lib
OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
USERINCLUDE ../server
USERINCLUDE ../fileutils/inc
--- a/kerneltest/f32test/server/b_gen.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/server/b_gen.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -20,12 +20,10 @@
#include "t_server.h"
#include "t_chlffs.h"
-#ifdef __VC32__
- // Solve compilation problem caused by non-English locale
- #pragma setlocale("english")
-#endif
+#include "f32_test_utils.h"
+using namespace F32_Test_Utils;
-GLDEF_D RTest test(_L("B_GEN"));
+RTest test(_L("B_GEN"));
//
// File test - general test of local filing system routines
// (finishes with formating current device).
@@ -37,67 +35,64 @@
// GLREF_D P_DEVICE p_file;
// GLREF_D P_DEVICE p_wind,p_screen,p_cons;
-GLDEF_D TBuf<0x100> gNameBuf;
-GLDEF_D TBuf<0x100> gNameOut;
-GLDEF_D RFile gFile;
-GLDEF_D RFile gFileErr;
-GLDEF_D RFile gFile2;
-GLDEF_D RDir gDir;
-GLDEF_D RFormat gFormat;
-//GLDEF_D void *chan1,*chan2;
-GLDEF_D TFileName fBuf;
-//GLDEF_D TUint8 fBuf[P_FNAMESIZE];
+TBuf<0x100> gNameBuf;
+TBuf<0x100> gNameOut;
+RFile gFile;
+RFile gFileErr;
+RFile gFile2;
+RDir gDir;
+RFormat gFormat;
+TFileName fBuf;
+TInt gDriveNum = -1;
-LOCAL_D TBuf8<0x4000> gDataBuf;
-LOCAL_D TEntry gFileEntry;
-// LOCAL_D P_DINFO volInfo;
-LOCAL_D TVolumeInfo volInfo;
-// LOCAL_D P_NINFO nInfo;
-LOCAL_D TFileName pathBuf;
+static TBuf8<0x4000> gDataBuf;
+static TEntry gFileEntry;
+static TVolumeInfo volInfo;
+static TFileName pathBuf;
-LOCAL_D TInt NameErr=KErrBadName;
-LOCAL_D TInt DirErr=KErrPathNotFound;
-LOCAL_D TInt AccessErr=KErrAccessDenied;
-LOCAL_D TInt LockedErr=KErrInUse;
-LOCAL_D TInt ExistsErr=KErrAlreadyExists;
-LOCAL_D TInt NotExistsErr=KErrNotFound;
-LOCAL_D TInt EofErr=KErrEof;
-LOCAL_D TInt DeviceErr=KErrNotReady;
+const TInt NameErr=KErrBadName;
+const TInt DirErr=KErrPathNotFound;
+const TInt AccessErr=KErrAccessDenied;
+const TInt LockedErr=KErrInUse;
+const TInt ExistsErr=KErrAlreadyExists;
+const TInt NotExistsErr=KErrNotFound;
+const TInt EofErr=KErrEof;
+const TInt DeviceErr=KErrNotReady;
//LOCAL_D TInt NoFileSystemErr=KErrNotReady;
//LOCAL_D TInt NotSupportedErr=KErrNotSupported;
-LOCAL_D TInt ReadOnlyErr=KErrAccessDenied;
+const TInt ReadOnlyErr=KErrAccessDenied;
-LOCAL_D TInt P_FASTREAM=EFileStream;
-LOCAL_D TInt P_FAEXEC=0;
-LOCAL_D TInt P_FAMOD=KEntryAttArchive;
-LOCAL_D TInt P_FAREAD=KEntryAttReadOnly;
+const TInt P_FASTREAM=EFileStream;
+const TInt P_FAEXEC=0;
+const TInt P_FAMOD=KEntryAttArchive;
+const TInt P_FAREAD=KEntryAttReadOnly;
//LOCAL_D TInt P_FAHIDDEN=KEntryAttHidden;
//LOCAL_D TInt P_FASYSTEM=KEntryAttSystem;
-//LOCAL_C TInt P_FAVOLUME=KEntryAttVolume;
-LOCAL_C TInt P_FADIR=KEntryAttDir;
-LOCAL_C TInt P_FRANDOM=0;
-LOCAL_C TInt P_FABS=ESeekStart;
+//static TInt P_FAVOLUME=KEntryAttVolume;
+const TInt P_FADIR=KEntryAttDir;
+const TInt P_FRANDOM=0;
+const TInt P_FABS=ESeekStart;
-LOCAL_C TInt P_FUPDATE=EFileWrite;
+const TInt P_FUPDATE=EFileWrite;
-LOCAL_C void doError(const TDesC &aMess, TInt anErr, TInt line)
+static void doError(const TDesC &aMess, TInt anErr, TInt line)
{
test.Printf(_L("%S failed at line %d. Error %d\n"),&aMess, line, anErr);
test(0);
}
#define Error(aMess, anErr) doError(aMess, anErr, __LINE__)
-LOCAL_C void doError2(const TDesC &aMess, TInt anErr, TInt line, TInt callLine)
+static void doError2(const TDesC &aMess, TInt anErr, TInt line, TInt callLine)
{
test.Printf(_L("%S failed at line %d. Error %d. Called from line %d\n"),&aMess, line, anErr, callLine); \
test(0);
}
#define Error2(aMess, anErr, line) doError2(aMess, anErr, __LINE__, line)
-LOCAL_C void testWrite(const TDesC& aName,TInt aLen,TInt32 aSize,TBool aShouldChange)
+static void testWrite(const TDesC& aName,TInt aLen,TInt32 aSize,TBool aShouldChange)
//
// Write to a file
//
@@ -123,7 +118,7 @@
Error(_L("Size check 602"),0);
}
-LOCAL_C void testSetEof(const TDesC& aName,TUint32 aPos,TBool aShouldChange)
+static void testSetEof(const TDesC& aName,TUint32 aPos,TBool aShouldChange)
//
// Set the end of a file
//
@@ -148,7 +143,7 @@
}
-LOCAL_C void testDir(const TDesC& aDirName)
+static void testDir(const TDesC& aDirName)
//
// Create a directory
//
@@ -173,7 +168,7 @@
/*
-LOCAL_C void testNodeInfo(const TDesC& aName,TInt type,TInt anErr)
+static void testNodeInfo(const TDesC& aName,TInt type,TInt anErr)
//
// Test p_ninfo.
//
@@ -193,7 +188,7 @@
}
*/
-LOCAL_C void testDeviceInfo(const TDesC& aDeviceName,TInt anErr)
+static void testDeviceInfo(const TDesC& aDeviceName,TInt anErr)
//
// Test p_dinfo.
//
@@ -218,7 +213,7 @@
}
}
-LOCAL_C void testFileInfo(const TDesC& aFileName,TInt anErr)
+static void testFileInfo(const TDesC& aFileName,TInt anErr)
//
// Test entry info
//
@@ -247,7 +242,7 @@
}
}
-LOCAL_C void testRenameFromRoot(const TDesC& aRName,const TDesC& aDName)
+static void testRenameFromRoot(const TDesC& aRName,const TDesC& aDName)
//
//
//
@@ -263,7 +258,7 @@
Error(_L("Delete 92"),c);
}
-LOCAL_C void testRenameToRoot(const TDesC& pName,const TDesC& rName)
+static void testRenameToRoot(const TDesC& pName,const TDesC& rName)
//
//
//
@@ -282,7 +277,7 @@
Error(_L("Delete 91"),c);
}
-LOCAL_C void verifyTestPat1()
+static void verifyTestPat1()
//
//
//
@@ -320,7 +315,7 @@
test(err == KErrNone);
}
-LOCAL_C void testRename()
+static void testRename()
//
// Test TheFs.Rename function.
//
@@ -475,7 +470,7 @@
TestINC103141(); // PDEF104017
}
-LOCAL_C void testDelete()
+static void testDelete()
//
// Test RFs::Delete function.
//
@@ -501,7 +496,7 @@
Error(_L("Delete 504"),c);
}
-LOCAL_C void testUnique(TUint fileFormat)
+static void testUnique(TUint fileFormat)
//
// Test RFile::Temp
//
@@ -525,7 +520,7 @@
Error(_L("Delete"),c);
}
-LOCAL_C void testFileName(const TDesC& aFileName,TInt res)
+static void testFileName(const TDesC& aFileName,TInt res)
//
//
//
@@ -556,8 +551,7 @@
}
}
-#if defined(_UNICODE)
-LOCAL_C void testFileName(const TDesC8& aFileName,TInt res)
+static void testFileName(const TDesC8& aFileName,TInt res)
//
// Defined to cope with all the instances of testFileName(gDataBuf,...)
//
@@ -565,9 +559,8 @@
TPtrC gDataBuf16((TText*)aFileName.Ptr(),gDataBuf.Size()/sizeof(TText8));
testFileName(gDataBuf16,res);
}
-#endif
-LOCAL_C void testVolumeName(const TDesC& aVolumeName,TInt aResultExpected)
+static void testVolumeName(const TDesC& aVolumeName,TInt aResultExpected)
//
//
//
@@ -605,7 +598,7 @@
}
#define testMakeDir(aDirName, res) TestMakeDirLine(aDirName, res, __LINE__)
-LOCAL_C void TestMakeDirLine(const TDesC& aDirName,TInt res, TInt line)
+static void TestMakeDirLine(const TDesC& aDirName,TInt res, TInt line)
//
//
//
@@ -663,8 +656,8 @@
}
}
-#if defined(_UNICODE)
-LOCAL_C void TestMakeDirLine(const TDesC8& aDirName, TInt res, TInt line)
+
+static void TestMakeDirLine(const TDesC8& aDirName, TInt res, TInt line)
//
// Defined to cope with all the instances of testMakeDir(gDataBuf,...)
//
@@ -674,10 +667,10 @@
// Not sizeof(TText16) since gDataBuf is a TBuf*!
TestMakeDirLine(gDataBuf16, res, line);
}
-#endif
+
#ifdef TEST_MEDIA
-LOCAL_C void testMedia(const TDesC& instructions,TInt anErr)
+static void testMedia(const TDesC& instructions,TInt anErr)
//
//
//
@@ -713,11 +706,25 @@
}
#endif
-GLDEF_C void CallTestsL()
-//
-// Do All tests
-//
+void CallTestsL()
{
+
+ //-- set up console output
+ F32_Test_Utils::SetConsole(test.Console());
+
+ TInt nRes=TheFs.CharToDrive(gDriveToTest, gDriveNum);
+ test(nRes==KErrNone);
+
+ PrintDrvInfo(TheFs, gDriveNum);
+
+ //-- quick format the drive, if it isn't the emulator's C:
+ if(!Is_Win32(TheFs, gDriveNum))
+ {
+ nRes = FormatDrive(TheFs, gDriveNum, ETrue);
+ test(nRes==KErrNone);
+ }
+
+ //-----------------------------------
TInt c;
TInt i,count;
TInt pos;
@@ -1452,37 +1459,15 @@
if (c==LockedErr || c==AccessErr)
{
test.Printf(_L("Format: locked, no test\n"));
- goto noFormat;
}
+ else
+ {
Error(_L("Format lock check"),c);
}
+ }
-// if ((c=p_read(chan2,&count,2))<0)
-// {
-// if (c==NotSupportedErr)
-// {
-// test.Printf(_L("Format: not supported, no test\n"));
-// goto noFormatClose;
-// }
-// Error(_L("Read format count"),c);
-// }
-// for (i=1;;i++)
-// {
-// if ((c=g(chan2,&val,2))<0)
-// {
-// if (c==EofErr)
-// break;
-// Error(_L("Format"),c);
-// }
-// test.Printf(_L("\r%05u %05u\n"),i,val);
-// }
-// if ((i-1)!=count)
-// Error(_L("Format count"),i);
-// noFormatClose:
-// if ((c=p_close(chan2))!=KErrNone)
-// Error(_L("Close"),c);
-noFormat:
gFormat.Close();
+
DeleteTestDirectory();
}
--- a/kerneltest/f32test/server/t_falsespace.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/server/t_falsespace.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1062,13 +1062,6 @@
{
//-- set up console output
Fat_Test_Utils::SetConsole(test.Console());
-
-
- if (gSessionPath[0]=='C') //only test on non C drives
- {
- test.Printf(_L("TEST NOT RUN FOR THIS DRIVE"));
- return;
- }
if (UserSvr::DebugMask(2)&0x00000002) // TESTFAST mode set? (for automated test builds)
if(IsTestingLFFS())
@@ -1086,6 +1079,23 @@
r=RFs::DriveToChar(gTestDrive,gCh);
test(r==KErrNone);
+ TDriveInfo drv;
+ r = TheFs.Drive(drv, gTestDrive);
+ test(r == KErrNone);
+
+ if (Is_Win32(TheFs, gTestDrive))
+ {
+ test.Printf(_L("Skipping on emulator %C: drive\n"), gSessionPath[0]);
+ return;
+ }
+
+ // do not run this test on RAM drive
+ if (drv.iType == EMediaRam)
+ {
+ test.Printf(_L("Test can't run on RAM drive %C:\n"), gSessionPath[0]);
+ return;
+ }
+
//-- print drive information
PrintDrvInfo(TheFs, gTestDrive);
--- a/kerneltest/f32test/server/t_locate.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/server/t_locate.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -162,7 +162,7 @@
err = TheFs.Drive(info, i);
test( err == KErrNone );
- if( info.iDriveAtt & KDriveAttRemovable )
+ if(( info.iDriveAtt & KDriveAttRemovable ) && !( info.iDriveAtt & KDriveAttLogicallyRemovable ))
{
if ( ( info.iType != EMediaNotPresent) && (info.iType != EMediaUnknown) && (info.iType != EMediaCdRom) )
--- a/kerneltest/f32test/server/t_main.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/server/t_main.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -662,12 +662,24 @@
test.Printf(_L("DriveCacheFlags = %08X\n"), gDriveCacheFlags);
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ test.Printf(_L("\n"));
+
+ TInt orgSessionCount;
+ r = controlIo(TheFs,theDrive, KControlIoSessionCount, orgSessionCount);
+ test(r==KErrNone);
+ test.Printf(_L("Session count start=%d\n"),orgSessionCount);
+
+ TInt orgObjectCount;
+ r = controlIo(TheFs,theDrive, KControlIoObjectCount, orgObjectCount);
+ test(r==KErrNone);
+ test.Printf(_L("Object count start=%d\n"),orgObjectCount);
+
+
TPckgBuf<TIOCacheValues> pkgOrgValues;
TIOCacheValues& orgValues=pkgOrgValues();
r = controlIo(TheFs,theDrive, KControlIoCacheCount, orgValues);
test_KErrNone(r);
- test.Printf(_L("\n"));
test.Printf(_L("Requests on close queue at start=%d\n"),orgValues.iCloseCount);
test.Printf(_L("Requests on free queue at start=%d\n"),orgValues.iFreeCount);
test.Printf(_L("Requests dynamically allocated at start=%d\n"),orgValues.iAllocated);
@@ -702,6 +714,80 @@
TheFs.SetAllocFailure(gAllocFailOff);
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ // Close and then re-open the main file server session to force the closure of
+ // any sub-sessions which may have been left open....
+ // NB: This won't help if the test has opened another session & left sub-sessions open.
+ TheFs.Close();
+ r=TheFs.Connect();
+ test(r==KErrNone);
+
+ // Display the file cache stats before closing the file queue
+ TFileCacheStats endFileCacheStats;
+ r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
+ test_Value(r, r == KErrNone || r == KErrNotSupported);
+ test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
+ endFileCacheStats.iFreeCount,
+ endFileCacheStats.iUsedCount,
+ endFileCacheStats.iAllocatedSegmentCount,
+ endFileCacheStats.iLockedSegmentCount,
+ endFileCacheStats.iFilesOnClosedQueue);
+
+
+ // Wait up to 3 seconds for all file server sessions & objects to close
+ // and then test session & object counts haven't changed
+ TInt endSessionCount = 0;
+ TInt endObjectCount = 0;
+ for (TInt n=0; n<3; n++)
+ {
+ // Flush the closed files queue as a file-cache object on the closed queue is counted as an open object
+ test.Printf(_L("Flushing close queue...\n"));
+ r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles);
+ test_KErrNone(r);
+
+ r = controlIo(TheFs,theDrive, KControlIoSessionCount, endSessionCount);
+ test(r==KErrNone);
+ test.Printf(_L("Session count end=%d\n"),endSessionCount);
+
+ r = controlIo(TheFs,theDrive, KControlIoObjectCount, endObjectCount);
+ test(r==KErrNone);
+ test.Printf(_L("Object count end=%d\n"),endObjectCount);
+
+ if (endSessionCount == orgSessionCount && endObjectCount == orgObjectCount)
+ break;
+
+ test.Printf(_L("Warning: Session/object count leak\n"));
+ User::After(1000000);
+ }
+
+ // some tests don't close their sessions, so this test won't work until
+ // all the tests are fixed :
+// test(endSessionCount == orgSessionCount);
+// test(endObjectCount == orgObjectCount);
+
+
+ // Test that the File cache hasn't leaked ....
+ r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
+ test_Value(r, r == KErrNone || r == KErrNotSupported);
+ test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
+ endFileCacheStats.iFreeCount,
+ endFileCacheStats.iUsedCount,
+ endFileCacheStats.iAllocatedSegmentCount,
+ endFileCacheStats.iLockedSegmentCount,
+ endFileCacheStats.iFilesOnClosedQueue);
+ if (r == KErrNone)
+ {
+ test(startFileCacheStats.iFreeCount == endFileCacheStats.iFreeCount);
+ test(startFileCacheStats.iUsedCount == endFileCacheStats.iUsedCount);
+ test(startFileCacheStats.iAllocatedSegmentCount == endFileCacheStats.iAllocatedSegmentCount);
+ test(startFileCacheStats.iLockedSegmentCount == endFileCacheStats.iLockedSegmentCount);
+ test(startFileCacheStats.iFileCount == endFileCacheStats.iFileCount);
+ }
+#endif
+
+
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ // Test that the request allocator hasn't leaked...
TPckgBuf<TIOCacheValues> pkgValues;
TIOCacheValues& values=pkgValues();
r = controlIo(TheFs,theDrive, KControlIoCacheCount, values);
@@ -723,42 +809,6 @@
// + 1 (because we used one request to issue KControlIoCacheCount)
// If this doesn't equate then this implies a request leak
test(values.iTotalCount == values.iCloseCount + values.iFreeCount + 1);
-
- // File cache
- TFileCacheStats endFileCacheStats;
- r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
- test_Value(r, r == KErrNone || r == KErrNotSupported);
-
- test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
- endFileCacheStats.iFreeCount,
- endFileCacheStats.iUsedCount,
- endFileCacheStats.iAllocatedSegmentCount,
- endFileCacheStats.iLockedSegmentCount,
- endFileCacheStats.iFilesOnClosedQueue);
-
- // flush closed files queue
- test.Printf(_L("Flushing close queue..."));
- r = TheFs.ControlIo(theDrive, KControlIoFlushClosedFiles);
- test_KErrNone(r);
-
- r = controlIo(TheFs,theDrive, KControlIoFileCacheStats, endFileCacheStats);
- test_Value(r, r == KErrNone || r == KErrNotSupported);
- test.Printf(_L("File cache: Cachelines (free %d, used %d), Segments(allocated %d locked %d). Closed files(%d)\n"),
- endFileCacheStats.iFreeCount,
- endFileCacheStats.iUsedCount,
- endFileCacheStats.iAllocatedSegmentCount,
- endFileCacheStats.iLockedSegmentCount,
- endFileCacheStats.iFilesOnClosedQueue);
-
-
- if (r == KErrNone)
- {
- test(startFileCacheStats.iFreeCount == endFileCacheStats.iFreeCount);
- test(startFileCacheStats.iUsedCount == endFileCacheStats.iUsedCount);
- test(startFileCacheStats.iAllocatedSegmentCount == endFileCacheStats.iAllocatedSegmentCount);
- test(startFileCacheStats.iLockedSegmentCount == endFileCacheStats.iLockedSegmentCount);
- test(startFileCacheStats.iFileCount == endFileCacheStats.iFileCount);
- }
#endif
TheFs.Close();
--- a/kerneltest/f32test/server/t_rename.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/server/t_rename.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -15,6 +15,7 @@
//
//
+#define __E32TEST_EXTENSION__
#include <f32file.h>
#include <e32test.h>
#include "t_server.h"
@@ -397,6 +398,83 @@
}
+//-------------------------------------------------------------------
+/**
+ Create a directory; create many files in it (the directory will become more that 1 cluster)
+ Then rename every file in this directory to a new name.
+*/
+void TestRenameManyFilesInTheSameDir()
+{
+ test.Next(_L("TestRenameManyFilesInTheSameDir"));
+
+ if(Is_Win32(TheFs, gDriveNum))
+ {
+ test.Printf(_L("Skipping on WINS drive\n"));
+ return;
+ }
+
+ _LIT(KDir, "\\dir1\\");
+ _LIT(KFile, "filename_long-");
+
+ //-- the number of files is chosen the way to have the directory file at least 2 clusters long (on FAT)
+ //-- "filename_long-XXX" will correspond to 2 VFAT entries in the directory; max. cluster size of FAT is 32K
+ //-- 2*32*600 = 38400 > 32K
+ const TInt KNumFiles = 600;
+
+ TName fName;
+ TInt i;
+ TInt nRes;
+
+ //-- quick format the drive
+ nRes = FormatDrive(TheFs, gDriveNum, ETrue);
+ test_KErrNone(nRes);
+
+ MakeDir(KDir);
+
+ //-- create a number of files in a single directory, it shall be larger than 1 cluster.
+ for(i=0; i<KNumFiles; ++i)
+ {
+ fName.Format(_L("%S%S%03d"), &KDir, &KFile, i);
+ nRes = CreateEmptyFile(TheFs, fName, 0);
+ test_KErrNone(nRes);
+ }
+
+ //-- rename all files in the same directory
+ TName fNameNew;
+ for(i=0; i<KNumFiles; ++i)
+ {
+ fName.Format(_L("%S%S%03d"), &KDir, &KFile, i);
+ fNameNew.Format(_L("%S%S%03d_new"), &KDir, &KFile, i);
+
+ nRes = TheFs.Rename(fName, fNameNew);
+ test_KErrNone(nRes);
+
+ }
+
+ fName.Format(_L("%c:"), gDriveNum+'A');
+ nRes = TheFs.CheckDisk(fName);
+ test(nRes == KErrNone || nRes == KErrNotSupported);
+
+ //-- clean up
+ for(i=0; i<KNumFiles; ++i)
+ {
+ fNameNew.Format(_L("%S%S%03d_new"), &KDir, &KFile, i);
+ nRes = TheFs.Delete(fNameNew);
+ test_KErrNone(nRes);
+ }
+
+ fName.Format(_L("%c:"), gDriveNum+'A');
+ nRes = TheFs.CheckDisk(fName);
+ test(nRes == KErrNone || nRes == KErrNotSupported);
+
+
+ nRes = TheFs.RmDir(KDir);
+ test(nRes == KErrNone);
+
+
+}
+
+
void CallTestsL(void)
{
@@ -424,6 +502,7 @@
TestRFileRename();
TestEikonRename();
TestReplaceAndRename();
+ TestRenameManyFilesInTheSameDir();
if(!Is_Win32(TheFs, gDriveNum))
{
--- a/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -31,8 +31,13 @@
#include "cdisplay.h"
// Display positions and test constants
+
+// Available drives
+static const TInt KStartRow_AvailableDrives = 1;
+_LIT(KAvailDriveMsg, "Drives: ");
+
// Number of attached devices
-static const TInt KRow_DevicesNumber = 13;
+static const TInt KRow_DevicesNumber = 2;
_LIT(KMsg_DevicesAttached, "USB Devices Attached = %d");
// Device Map
@@ -41,45 +46,46 @@
_LIT(KMsg_DeviceMap_DriveList, "%d: "); // [drive index]
_LIT(KMsg_DeviceMap_DriveLunEntry, "%c "); // [drive letter]
-
// Drive Map
static const TInt KStartRow_DriveMap = KStartRow_DeviceMap + KMaxRows_DeviceMap;
static const TInt KMaxRows_DriveMap = 4;
+
+// Drive info
+static const TInt KStartRow_MsgWindow = KStartRow_DriveMap + KMaxRows_DriveMap + 2;
+
_LIT(KMsg_DriveMap_EntryLetter, "%c token = %d"); // [drive letter] [token]
_LIT(KDbgMsg_DriveMap_EntryLetter, "*** %c token = %d"); // [drive letter] [token]
+
+static const TInt KRowScrollWindowStart = KStartRow_MsgWindow;
// System Status
-static const TInt KStartRow_UpTime = 28;
+static TPoint KPointSystemStatus(5, 0);
_LIT(KMsg_UpTime, "up time : %dh:%dm:%ds "); // use trailing space to overwrite any leftover chars in line
-static const TInt KStartRow_MemoryFree = 29;
+//static const TInt KStartRow_MemoryFree = 1 + KStartRow_SystemStatus;
+static TPoint KPointMemoryFree(5, 1);
_LIT(KMsg_MemoryFree, "mem (bytes) : 0x%X");
// User Keys
-static const TInt KStartRow_UserKeys = 25;
+static const TPoint KPointUser1Keys(5,2);
_LIT(KMsgUser1Keys, "[Esc]=Quit [A-Z]=DriveInfo");
-_LIT(KMsgUser2Keys, "[F5]=Hub update");
+static const TPoint KPointUser2Keys(5,3);
+_LIT(KMsgUser2Keys, "[F5|SPACE]=Hub update");
// Scroll Window status
_LIT(KScrollWindowStatus, "Page %d of %d");
-// Available drives
-static const TInt KStartRow_AvailableDrives = 1;
-_LIT(KAvailDriveMsg, "Drives: ");
_LIT(KDriveAtts,"DriveList %c: %02x ");
-// Drive info
-static const TInt KStartRow_MsgWindow = 3;
-static const TInt KStartRow_DriveInfo = KStartRow_MsgWindow;
// ****************************************************************************
-CScrollWindow* CScrollWindow::NewL(CConsoleBase& aConsole)
+CScrollWindow* CScrollWindow::NewL(CConsoleBase& aConsole, TInt aStartRow, TInt aEndRow)
{
- CScrollWindow* r = new (ELeave) CScrollWindow(aConsole);
+ CScrollWindow* r = new (ELeave) CScrollWindow(aConsole, aStartRow, aEndRow);
CleanupStack::PushL(r);
r->ConstructL();
CleanupStack::Pop(r);
@@ -89,13 +95,17 @@
void CScrollWindow::ConstructL()
{
-
}
+_LIT(KTxtPanic,"HUSBCONSAPP");
-CScrollWindow::CScrollWindow(CConsoleBase& aConsole)
-: iConsole(aConsole)
+CScrollWindow::CScrollWindow(CConsoleBase& aConsole, TInt aStartRow, TInt aEndRow)
+: iConsole(aConsole),
+ iStartRow(aStartRow),
+ iEndRow(aEndRow),
+ iPageLength(iEndRow - iStartRow)
{
+ __ASSERT_ALWAYS(iEndRow > iStartRow, User::Panic(KTxtPanic, -1));
}
CScrollWindow::~CScrollWindow()
@@ -130,12 +140,12 @@
void CScrollWindow::Update()
{
- TInt line = iPage * KPageLength;
+ TInt line = iPage * iPageLength;
- TInt row = KStartRow_DriveInfo;
+ TInt row = iStartRow;
do
{
- iConsole.SetPos(0, row + line%KPageLength);
+ iConsole.SetPos(0, row + line%iPageLength);
if (line < iLineArray.Count())
{
iConsole.Printf(iLineArray[line]);
@@ -143,14 +153,15 @@
iConsole.ClearToEndOfLine();
line++;
}
- while (((line-1)%KPageLength) != (KPageLength - 1));
- iConsole.SetPos(0, KStartRow_DriveInfo + KPageLength);
- iConsole.Printf(KScrollWindowStatus, iPage + 1, iLineArray.Count()/KPageLength + 1);
+ while (((line-1)%iPageLength) != (iPageLength - 1));
+
+ iConsole.SetPos(0, iStartRow + iPageLength);
+ iConsole.Printf(KScrollWindowStatus, iPage + 1, iLineArray.Count()/iPageLength + 1);
}
void CScrollWindow::PageInc()
{
- TInt lastPage = iLineArray.Count()/KPageLength;
+ TInt lastPage = iLineArray.Count()/iPageLength;
if (iPage == lastPage)
{
iPage = 0;
@@ -166,7 +177,7 @@
{
if (iPage == 0)
{
- TInt lastPage = iLineArray.Count()/KPageLength;
+ TInt lastPage = iLineArray.Count()/iPageLength;
iPage = lastPage;
}
else
@@ -176,7 +187,6 @@
}
-
CDisplay* CDisplay::NewLC(RFs& aFs, CConsoleBase& aConsole)
{
CDisplay* r = new (ELeave) CDisplay(aFs, aConsole);
@@ -187,8 +197,8 @@
void CDisplay::ConstructL()
- {
- iScrollWindow = CScrollWindow::NewL(iConsole);
+ {
+ iScrollWindow = CScrollWindow::NewL(iConsole, KRowScrollWindowStart, iScreenSize.iHeight - iFooterY - 4);
}
@@ -197,6 +207,9 @@
iConsole(aConsole)
{
iConsole.ClearScreen();
+ iScreenSize = iConsole.ScreenSize();
+ // Origin of footer
+ iPointFooter = TPoint(iFooterX, iScreenSize.iHeight - iFooterY - 2);
}
@@ -208,9 +221,9 @@
void CDisplay::Menu()
{
- iConsole.SetPos(0, KStartRow_UserKeys);
+ SetFooterPos(KPointUser1Keys);
iConsole.Printf(KMsgUser1Keys);
- iConsole.SetPos(0, KStartRow_UserKeys + 1);
+ SetFooterPos(KPointUser2Keys);
iConsole.Printf(KMsgUser2Keys);
iCursorPos = iConsole.CursorPos();
}
@@ -592,7 +605,6 @@
line->Format(KFree, aVolumeInfo.iFree);
line = iScrollWindow->NewLineL();
line->Format(KVolName, &aVolumeInfo.iName);
-
}
@@ -600,14 +612,15 @@
{
TUint totalMins = aUpTime/60;
TUint totalHrs = totalMins/60;
- iConsole.SetPos(0, KStartRow_UpTime);
+
+ SetFooterPos(KPointSystemStatus);
iConsole.Printf(KMsg_UpTime, totalHrs, totalMins%60, aUpTime%60);
CursorHome();
}
void CDisplay::MemoryFree(TInt aBytes) const
{
- iConsole.SetPos(0, KStartRow_MemoryFree);
+ SetFooterPos(KPointMemoryFree);
iConsole.Printf(KMsg_MemoryFree, aBytes);
CursorHome();
}
@@ -684,6 +697,7 @@
TBool CMessageKeyProcessor::HandleKeyL(TKeyCode aKeyCode)
{
TBool done = EFalse;
+
if (TChar(aKeyCode).IsAlpha())
{
iDisplay.GetDriveInfoL(aKeyCode);
@@ -694,6 +708,7 @@
switch (aKeyCode)
{
case EKeyF5:
+ case EKeySpace:
{
// Update USB status
iUsbOtgSession.DeviceInserted();
@@ -703,11 +718,13 @@
case EKeyUpArrow:
case EKeyPageUp:
+ case '[':
iDisplay.PageDec();
iDisplay.DriveInfo();
break;
case EKeyDownArrow:
case EKeyPageDown:
+ case ']':
iDisplay.PageInc();
iDisplay.DriveInfo();
break;
--- a/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.h Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.h Sun Mar 14 13:15:32 2010 +0000
@@ -33,11 +33,11 @@
class CScrollWindow: public CBase
{
public:
- static CScrollWindow* NewL(CConsoleBase& aConsole);
+ static CScrollWindow* NewL(CConsoleBase& aConsole, TInt aStartRow, TInt aEndRow);
~CScrollWindow();
private:
- CScrollWindow(CConsoleBase& aConsole);
+ CScrollWindow(CConsoleBase& aConsole, TInt aStartRow, TInt aEndRow);
void ConstructL();
public:
@@ -56,7 +56,9 @@
RArray<TLine> iLineArray;
TInt iPage;
- static const TInt KPageLength = 8;
+ const TInt iStartRow;
+ const TInt iEndRow;
+ const TInt iPageLength;
};
@@ -100,12 +102,20 @@
void CursorHome() const;
-private:
+ void SetFooterPos(TPoint iPos) const;
+
+private:
+ static const TInt iFooterX = 0;
+ static const TInt iFooterY = 4;
+
RFs& iFs;
CConsoleBase& iConsole;
+ TSize iScreenSize;
TPoint iCursorPos;
+ TPoint iPointFooter;
+
CScrollWindow* iScrollWindow;
};
@@ -115,7 +125,11 @@
iConsole.SetPos(iCursorPos.iX, iCursorPos.iY);
}
-
+inline void CDisplay::SetFooterPos(TPoint iPos) const
+ {
+ TPoint pos = iPos + iPointFooter;
+ iConsole.SetPos(pos.iX, pos.iY);
+ }
class CMessageKeyProcessor : public CActive
{
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -928,7 +928,7 @@
DataOutReadRequest(deviceDataLength);
}
#else
- DataOutRead(deviceDataLength);
+ DataOutReadRequest(deviceDataLength);
#endif
return;
}
--- a/kerneltest/f32test/smassstorage/src/t_ms_mountstart.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/kerneltest/f32test/smassstorage/src/t_ms_mountstart.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -701,6 +701,8 @@
fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients);
test(trsClientComplete == KRequestPending);
+ fs.NotifyDismountCancel(trsClientComplete);
+
fs.Close();
dismountFs1.Close();
}
--- a/userlibandfileserver/fileserver/etshell/ts_com.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/etshell/ts_com.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -43,7 +43,7 @@
TShellCommand(_L("CD"),_L("Change the current directory for a drive"),_L("[path] [/d]\n\n /d - Change drive"),TShellCommand::EDSwitch,ShellFunction::Cd),
TShellCommand(_L("CHKDEPS"),_L("Check the dependencies of an executable or a Dll (ARM only)"),_L("[Filename.EXE] or [Filename.DLL]"),0,ShellFunction::ChkDeps),
TShellCommand(_L("CHKDSK"),_L("Check disk for corruption"),_L("[drive:] [/s][/f|/u]\n\n/s - start ScanDrive instead of CheckDisk\n/f - finalise drive\n/u - unfinalise drive"),TShellCommand::ESSwitch|TShellCommand::EFSwitch|TShellCommand::EUSwitch,ShellFunction::ChkDsk),
- TShellCommand(_L("COPY"),_L("Copy one (or more) file(s)"),_L("source [destination]"),TShellCommand::ESSwitch,ShellFunction::Copy),
+ TShellCommand(_L("COPY"),_L("Copy one (or more) file(s), overwriting existing one(s)"),_L("source [destination]"),TShellCommand::ESSwitch,ShellFunction::Copy),
TShellCommand(_L("DEL"),_L("Delete one file"),_L("[drive:][path][filename]"),TShellCommand::ESSwitch,ShellFunction::Del),
TShellCommand(_L("DIR"),_L("Show directory contents"),_L("[drive:][path][filename] [/p][/w]\n\n /p - Pause after each screen of information\n /w - Wide format"),TShellCommand::EPSwitch|TShellCommand::EWSwitch|TShellCommand::EASwitch,ShellFunction::Dir),
// TShellCommand(_L("EDLIN"),_L("Edit a text file"),_L("[drive:][path][filename] [/p]\n\n /p - Pause after each screen of information"),TShellCommand::EPSwitch,ShellFunction::Edit),
@@ -403,6 +403,8 @@
// To append files, specify a single file for destination, but multiple files
// for source (using wildcards or file1+file2+file3 format).
//
+// Overwrites existing file(s).
+//
// My spec:
//
// COPY source [destination]
@@ -461,6 +463,7 @@
}
TBool recursive=((aSwitches&TShellCommand::ESSwitch)!=0);
+ // Automatically overwrites existing file(s)
TUint switches=(recursive) ? CFileMan::EOverWrite|CFileMan::ERecurse : CFileMan::EOverWrite;
r=CShell::TheFileMan->Copy(dirPath.FullName(),destination,switches);
if (r==KErrNone)
--- a/userlibandfileserver/fileserver/group/release.txt Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/group/release.txt Sun Mar 14 13:15:32 2010 +0000
@@ -1,3 +1,57 @@
+Version 2.00.2031
+=================
+(Made by vfebvre 26/01/2010)
+
+1. famustaf
+ 1. MINOR_CHANGE Add documentation to 'Copy' in Text Shell (TB9.2)
+ Added documentation to state that ShellFunction::Copy will overwrite existing file(s)
+
+
+Version 2.00.2030
+=================
+(Made by vfebvre 21/01/2010)
+
+1. dlyokhin
+ 1. PDEF143791 FAT: renaming many files in a directory corrupts short file names
+
+
+Version 2.00.2029
+=================
+(Made by vfebvre 19/01/2010)
+
+1. necliffo
+ 1. PDEF143913 WDP: T_locate fails on VASCO
+
+
+Version 2.00.2028
+=================
+(Made by vfebvre 15/01/2010)
+
+1. niccox
+ 1. PDEF143832 t_falsespace should not be run on drive if media type is EMediaRAM
+
+
+Version 2.00.2027
+=================
+(Made by vfebvre 15/01/2010)
+
+1. niccox
+ 1. PDEF143508 Host USB ModeSense10 command does not decode ModeDataLength
+ 2. MINOR_CHANGE usbtestclient corrections
+ 3. MINOR_CHANGE hostusbmsapp support for different screen sizes
+ 4. DEF143785 USB Host MS does not handle non-mass-storage drive correctly
+
+2. kaduan
+ 1. DEF143211 File system caching should be turned off on the S60 emulator
+ 2. DEF136627: T_HANDSHARE failed on NE1_TB_ARMV5.UDEB.SMPPAGE image
+
+3. migubarr
+ 1. DEF143592: t_ms_mountstart fails on H4 and VASCO
+
+4. dlyokhin
+ 1. PDEF143794 FAT: deleting VFAT entryset is not optimal
+
+
Version 2.00.2026
=================
(Made by vfebvre 17/12/2009)
--- a/userlibandfileserver/fileserver/inc/f32dbg.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/inc/f32dbg.h Sun Mar 14 13:15:32 2010 +0000
@@ -184,6 +184,9 @@
const TInt KControlIoFileCacheConfig=KMaxTInt-19;
const TInt KControlIoSimulateFileCacheWriteFailure=KMaxTInt-20;
+const TInt KControlIoSessionCount=KMaxTInt-21;
+const TInt KControlIoObjectCount=KMaxTInt-22;
+
const TInt KNCDebugNotifierValue=-500000; // between 0 and 1 second
GLREF_D TInt DebugNCNotifier;
--- a/userlibandfileserver/fileserver/inc/f32file.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/inc/f32file.h Sun Mar 14 13:15:32 2010 +0000
@@ -1830,6 +1830,8 @@
#define EFSRV_IMPORT_C IMPORT_C
#endif
+// forward declarations from e32ldr_private.h
+class RFileClamp;
class RFs : public RSessionBase
/**
@@ -2167,7 +2169,6 @@
};
__ASSERT_COMPILE(_FOFF(TVolFormatParam, iUId) == 0);
-__ASSERT_COMPILE(sizeof(TVolFormatParam) != sizeof(TLDFormatInfo));
/** package buffer for the objects of class TVolFormatParamBuf */
--- a/userlibandfileserver/fileserver/inc/f32ver.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/inc/f32ver.h Sun Mar 14 13:15:32 2010 +0000
@@ -58,6 +58,6 @@
@see TVersion
*/
-const TInt KF32BuildVersionNumber=2026;
+const TInt KF32BuildVersionNumber=2031;
//
#endif
--- a/userlibandfileserver/fileserver/sfat32/fat_dir_entry.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/fat_dir_entry.h Sun Mar 14 13:15:32 2010 +0000
@@ -97,8 +97,7 @@
inline void SetRuggedFatEntryId(TUint16 aId);
public:
- void InitializeAsVFat(TUint8 aCheckSum);
- void SetVFatEntry(const TDesC& aName,TInt aRemainderLen);
+ void SetVFatEntry(const TDesC& aName, TUint aRemainderLen, TUint8 aCheckSum);
void ReadVFatEntry(TDes16& aVBuf) const;
inline TBool IsLongNameStart() const;
inline TBool IsVFatEntry() const;
@@ -110,6 +109,8 @@
TUint8 iData[KSizeOfFatDirEntry]; ///< The directory entry data
};
+__ASSERT_COMPILE((sizeof(TFatDirEntry) == KSizeOfFatDirEntry));
+__ASSERT_COMPILE((sizeof(SFatDirEntry) == KSizeOfFatDirEntry));
#endif //FAT_DIR_ENTRY_H
--- a/userlibandfileserver/fileserver/sfat32/fat_dir_entry.inl Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/fat_dir_entry.inl Sun Mar 14 13:15:32 2010 +0000
@@ -77,7 +77,10 @@
@return The size of file or directory for this entry
*/
inline TUint32 TFatDirEntry::Size() const
- {return pDir->iSize;}
+ {
+ return pDir->iSize;
+ }
+
/**
@return True if the entry is erased
*/
@@ -155,33 +158,35 @@
@param aFileSize Size of the file
*/
inline void TFatDirEntry::SetSize(TUint32 aFileSize)
- {pDir->iSize=aFileSize;}
-/**
-Set the directory entry as erased
-*/
+ {
+ pDir->iSize=aFileSize;
+ }
+
+/** Set the directory entry as erased */
inline void TFatDirEntry::SetErased()
- {iData[0]=KEntryErasedMarker;}
-/**
-Set the current entry to refer to the current directory
-*/
+ {
+ iData[0]=KEntryErasedMarker;
+ }
+
+/** Set the current entry to refer to the current directory */
inline void TFatDirEntry::SetCurrentDirectory()
{
iData[0]='.';
Mem::Fill(&iData[1],KFatDirNameSize-1,' ');
}
-/**
-Set the current entry to refer to the parent directory
-*/
+
+/** Set the current entry to refer to the parent directory */
inline void TFatDirEntry::SetParentDirectory()
{
iData[0]='.';iData[1]='.';
Mem::Fill(&iData[2],KFatDirNameSize-2,' ');
}
-/**
-Set the current entry to be the end of directory marker
-*/
+
+/** Set the current entry to be the end of directory marker */
inline void TFatDirEntry::SetEndOfDirectory()
- {Mem::FillZ(&iData[0],KFatDirNameSize);}
+ {
+ Mem::FillZ(&iData[0],KFatDirNameSize);
+ }
/**
Get VFAT entry ID. Uset by Rugged FAT and Scan Drive to fix broken entries
@@ -202,21 +207,23 @@
}
-/**
-@return True if the entry is the start of a long name set of entries
-*/
+/** @return True if the entry is the start of a long name set of entries */
inline TBool TFatDirEntry::IsLongNameStart() const
- {return (TBool)((iData[0]&0x40) != 0);}
-/**
-@return True is the Entry is a VFat entry
-*/
+ {
+ return (iData[0] & 0x40);
+ }
+
+/** @return True is the Entry is a VFat entry */
inline TBool TFatDirEntry::IsVFatEntry() const
- {return (TBool)(Attributes()==KVFatEntryAttribute && IsEndOfDirectory()==EFalse);}
-/**
-@return The number of following VFat entries
-*/
+ {
+ return (Attributes()==KVFatEntryAttribute && IsEndOfDirectory() == EFalse);
+ }
+
+/** @return The number of following VFat entries */
inline TInt TFatDirEntry::NumFollowing() const
- {return (iData[0]&0x3F);}
+ {
+ return (iData[0]&0x3F);
+ }
inline TUint8 TFatDirEntry::CheckSum() const
@@ -226,7 +233,6 @@
}
-
/**
@return ETrue if the Directory entry contains garbage data
*/
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_std.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_std.h Sun Mar 14 13:15:32 2010 +0000
@@ -63,12 +63,13 @@
class TEntryPos
{
public:
- TEntryPos() {}
+ TEntryPos() : iCluster(EOF_32Bit), iPos(0) {}
TEntryPos(TInt aCluster,TUint aPos) : iCluster(aCluster), iPos(aPos) {}
inline TUint32 Cluster() const;
inline TUint32 Pos() const;
inline TBool operator==(const TEntryPos& aRhs) const;
+ inline void SetEndOfDir();
public:
TInt iCluster;
@@ -110,8 +111,13 @@
protected:
TDriveInterface();
+ ~TDriveInterface() {Close();}
+
+ //-- outlawed
TDriveInterface(const TDriveInterface&);
TDriveInterface& operator=(const TDriveInterface&);
+ void* operator new(TUint); //-- disable creating objets of this class on the heap.
+ void* operator new(TUint, void*);
TBool Init(CFatMountCB* aMount);
void Close();
@@ -491,14 +497,12 @@
/**
A wrapper around TDriveInterface providing its instantination and destruction.
- You must not create objects of this class, use DriveInterface() instead.
+ You must not create objects of this class, use DriveInterface() method for obtaining the reference to the driver interface.
*/
class XDriveInterface: public TDriveInterface
{
public:
- XDriveInterface() : TDriveInterface() {}
- ~XDriveInterface() {Close();}
- TBool Init(CFatMountCB* aMount) {return TDriveInterface::Init(aMount);}
+ using TDriveInterface::Init;
};
@@ -538,9 +542,13 @@
inline TInt ClusterRelativePos(TInt aPos) const;
inline TUint StartOfRootDirInBytes() const;
inline TUint32 UsableClusters() const;
+ inline TBool ClusterNumberValid(TUint32 aClusterNo) const;
inline TBool IsBadCluster(TInt aCluster) const;
+
inline TBool IsRuggedFSys() const;
inline void SetRuggedFSys(TBool aVal);
+ inline TUint32 AtomicWriteGranularityLog2() const;
+
inline TInt RootIndicator() const;
@@ -662,6 +670,24 @@
RArray<TShortName> iShortNameCandidates;
};
+
+ /** a helper class that describes a continuous chunk of diectory entries*/
+ class TEntrySetChunkInfo
+ {
+ public:
+ inline TEntrySetChunkInfo();
+ inline TBool operator==(const TEntrySetChunkInfo& aRhs);
+
+ //-- FAT entryset can't span more than 3 clusters/sectors
+ enum {KMaxChunks = 3};
+
+ public:
+ TEntryPos iEntryPos; ///< entryset chunk dir. starting position
+ TUint iNumEntries; ///< number of entries in the chunk
+ };
+
+
+ void DoEraseEntrySetChunkL(const TEntrySetChunkInfo& aEntrySetChunk);
TBool DoRummageDirCacheL(TUint anAtt,TEntryPos& aStartEntryPos,TFatDirEntry& aStartEntry,TEntryPos& aDosEntryPos,TFatDirEntry& aDosEntry,TDes& aFileName, const TFindHelper& aAuxParam, XFileCreationHelper* aFileCreationHelper, const TLeafDirData& aLeafDir) const;
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_std.inl Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_std.inl Sun Mar 14 13:15:32 2010 +0000
@@ -38,10 +38,29 @@
return (iCluster == aRhs.iCluster && iPos == aRhs.iPos);
}
+/** set "end of directory" indicator*/
+void TEntryPos::SetEndOfDir()
+ {
+ iCluster = EOF_32Bit;
+ }
+
//---------------------------------------------------------------------------------------------------------------------------------
// class CFatMountCB
+
+/** @return ETrue if the value of aClusterNo is valid*/
+inline TBool CFatMountCB::ClusterNumberValid(TUint32 aClusterNo) const
+ {
+ ASSERT(ConsistentState());
+
+ if(!aClusterNo && !Is32BitFat())
+ return ETrue; //-- root dir. cluster for FAT12/16
+
+ return (aClusterNo >= KFatFirstSearchCluster) && (aClusterNo < UsableClusters()+KFatFirstSearchCluster);
+ }
+
+
inline TInt CFatMountCB::RootDirectorySector() const
{return iVolParam.RootDirectorySector();}
@@ -159,17 +178,33 @@
/**
Returns whether the current mount is running as rugged Fat or not, this is held in the file system object
-@return Is rugged fat flag
+ @return ETrue if this is Rugged FAT
*/
TBool CFatMountCB::IsRuggedFSys() const
- {return Drive().IsRugged();}
+ {
+ return Drive().IsRugged();
+ }
/**
Sets the rugged flag in the file system object
@param Flag to set or clear the rugged flag
*/
void CFatMountCB::SetRuggedFSys(TBool aVal)
- {Drive().SetRugged(aVal);}
+ {
+ Drive().SetRugged(aVal);
+ }
+
+/**
+ @return Log2(Meida atomic write granularity).
+ This is mostly to be used in Rugged FAT mode, see IsRuggedFSys(). For Rugged FAT the media shall support atomic writes.
+ By default this is the sector (512 bytes)
+
+*/
+TUint32 CFatMountCB::AtomicWriteGranularityLog2() const
+ {
+ return KDefSectorSzLog2;
+ }
+
/** @return the usable clusters count for a volume */
TUint32 CFatMountCB::UsableClusters() const
@@ -338,6 +373,21 @@
}
+CFatMountCB::TEntrySetChunkInfo::TEntrySetChunkInfo()
+ :iNumEntries(KMaxTUint)
+ {
+ }
+
+
+TBool CFatMountCB::TEntrySetChunkInfo::operator==(const TEntrySetChunkInfo& aRhs)
+ {
+ ASSERT(&aRhs != this);
+ return (iNumEntries == aRhs.iNumEntries) && (iEntryPos==aRhs.iEntryPos);
+ }
+
+
+
+
//------- debug methods
#ifdef _DEBUG
/**
--- a/userlibandfileserver/fileserver/sfat32/sl_cache.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_cache.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -28,19 +28,12 @@
CWTCachePage* CWTCachePage::NewL(TUint32 aPageSizeLog2)
{
CWTCachePage* pSelf = new (ELeave)CWTCachePage;
- pSelf->ConstructL(aPageSizeLog2);
+
+ pSelf->iData.CreateMaxL(1 << aPageSizeLog2);
return pSelf;
}
-/**
- 2nd stage constructor.
- @param aPageSizeLog2 Log2(cache page size in bytes)
-*/
-void CWTCachePage::ConstructL(TUint32 aPageSizeLog2)
- {
- iData.CreateMaxL(1 << aPageSizeLog2);
- }
CWTCachePage::CWTCachePage()
{
@@ -82,46 +75,45 @@
@param aDrive reference to the driver for media access.
@param aNumPages number of cache pages to be created
- @param aPageSizeLog2 Log2 of the page size in bytes
+ @param aPageSizeLog2 Log2 of the page size in bytes, this is the cache read granularity
+ @param aWrGranularityLog2 Log2(cache write granularity)
@return a pointer to the created object.
*/
-CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2)
+CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
{
-#ifndef ENABLE_DEDICATED_DIR_CACHE
- //-- dedicated directory cache isn't enabled
- (void)aDrive; //-- supress compiler's warning
- (void)aClusterSizeLog2;
- return NULL;
-#else
-
- //-- dedicated directory cache is enabled, create it
- ASSERT(aPageSizeLog2);
- ASSERT(aNumPages);
CMediaWTCache* pSelf = new (ELeave) CMediaWTCache(aDrive);
CleanupStack::PushL(pSelf);
- pSelf->ConstructL(aNumPages, aPageSizeLog2);
+ pSelf->InitialiseL(aNumPages, aPageSizeLog2, aWrGranularityLog2);
CleanupStack::Pop();
return pSelf;
-
-#endif
}
/**
2nd stage constructor.
@param aNumPages number of pages in the directory cache.
- @param aPageSizeLog2 Log2(single cache page size in bytes)
+ @param aPageSizeLog2 Log2 of the page size in bytes, this is the cache read granularity
+ @param aWrGranularityLog2 Log2(cache write granularity)
*/
-void CMediaWTCache::ConstructL(TUint32 aNumPages, TUint32 aPageSizeLog2)
+void CMediaWTCache::InitialiseL(TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
{
ASSERT(aNumPages && aPageSizeLog2);
- __PRINT2(_L("#CMediaWTCache::CreateL() Pages=%d, PageSize=%d"), aNumPages, 1<<aPageSizeLog2);
+ __PRINT3(_L("#CMediaWTCache::InitialiseL() Pages=%d, PageSzLog2=%d, WrGrLog2:%d"), aNumPages, aPageSizeLog2, aWrGranularityLog2);
+
+ ASSERT(aNumPages);
+ ASSERT(aPageSizeLog2);
+
+ if(aWrGranularityLog2)
+ {
+ ASSERT(aWrGranularityLog2 >= KDefSectorSzLog2 && aWrGranularityLog2 <= aPageSizeLog2);
+ }
iPageSizeLog2 = aPageSizeLog2;
+ iWrGranularityLog2 = aWrGranularityLog2;
//-- create cache pages
for(TUint cnt=0; cnt<aNumPages; ++cnt)
@@ -369,14 +361,12 @@
@return 0 if aPosToSearch isn't cached, otherwise cache page size in bytes (see also aCachedPosStart).
*/
-TUint32 CMediaWTCache::PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart)
+TUint32 CMediaWTCache::PosCached(TInt64 aPosToSearch)
{
TInt nPage = FindPageByPos(aPosToSearch);
if(nPage <0 )
return 0; //-- cache page containing aPos not found
- aCachedPosStart = iPages[nPage]->iStartPos;
-
return PageSize();
}
@@ -483,9 +473,35 @@
if(dataLen <= bytesToPageEnd)
{//-- data section completely fits to the cache page
Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen); //-- update cache
+
+ //-- make small write a multiple of a write granularity size (if it is used at all)
+ //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
+ TPtrC8 desBlock(aDes);
+
+ if(iWrGranularityLog2)
+ {//-- write granularity is used
+ const TInt64 newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the write granularity size
+ TUint32 newLen = (TUint32)(aPos - newPos)+dataLen; //-- round block size up to the write granularity size
+ newLen = RoundUp(newLen, iWrGranularityLog2);
+
+ const TUint8* pd = pPage->PtrInCachePage(newPos);
+ desBlock.Set(pd, newLen);
+ aPos = newPos;
+ }
+
+
+ //-- write data to the media
+ const TInt nErr = iDrive.WriteCritical(aPos, desBlock);
+ if(nErr != KErrNone)
+ {//-- some serious problem occured during writing, invalidate cache.
+ InvalidateCache();
+ User::Leave(nErr);
+ }
+
}
else
{//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
+ //-- this is a very rare case.
TInt64 currMediaPos(aPos); //-- current media position
@@ -523,9 +539,6 @@
Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, dataLen);
}
- }// else(dataLen <= bytesToPageEnd)
-
-
//-- write data to the media
const TInt nErr = iDrive.WriteCritical(aPos,aDes);
if(nErr != KErrNone)
@@ -534,6 +547,10 @@
User::Leave(nErr);
}
+ }// else(dataLen <= bytesToPageEnd)
+
+
+
MakePageLRU(nPage); //-- push the page to the top of the priority list
}
--- a/userlibandfileserver/fileserver/sfat32/sl_cache.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_cache.h Sun Mar 14 13:15:32 2010 +0000
@@ -27,8 +27,6 @@
//---------------------------------------------------------------------------------------------------------------------------------
//-- dedicated FAT directory cache related stuff
-//-- if defined, a dedicated cache will be used for FAT directories
-#define ENABLE_DEDICATED_DIR_CACHE
//---------------------------------------------------------------------------------------------------------------------------------
@@ -64,13 +62,10 @@
/**
Finds out if the media position "aPosToSearch" is in the cache and returns cache page information in this case.
-
@param aPosToSearch linear media position to lookup in the cache
- @param aCachedPosStart if "aPosToSearch" is cached, here will be media position of this page start
-
@return 0 if aPosToSearch isn't cached, otherwise cache page size in bytes (see also aCachedPosStart).
*/
- virtual TUint32 PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart) = 0;
+ virtual TUint32 PosCached(TInt64 aPosToSearch) = 0;
/**
@return size of the cache in bytes. Can be 0.
@@ -116,7 +111,6 @@
public:
static CWTCachePage* NewL(TUint32 aPageSizeLog2);
- void ConstructL(TUint32 aPageSizeLog2);
~CWTCachePage();
@@ -148,9 +142,7 @@
public:
~CMediaWTCache();
- static CMediaWTCache* NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2);
-
- void ConstructL(TUint32 aNumPages, TUint32 aPageSizeLog2);
+ static CMediaWTCache* NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2);
//-- overloads from the base class
void ReadL (TInt64 aPos,TInt aLength,TDes8& aDes);
@@ -159,7 +151,7 @@
void InvalidateCachePage(TUint64 aPos);
- TUint32 PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart);
+ TUint32 PosCached(TInt64 aPosToSearch);
TUint32 CacheSizeInBytes() const;
void MakePageMRU(TInt64 aPos);
TUint32 PageSizeInBytesLog2() const;
@@ -171,6 +163,8 @@
CMediaWTCache();
CMediaWTCache(TDriveInterface& aDrive);
+ void InitialiseL(TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2);
+
inline TInt64 CalcPageStartPos(TInt64 aPos) const;
inline TUint32 PageSize() const;
@@ -183,10 +177,14 @@
protected:
TDriveInterface& iDrive; ///< reference to the driver for media access
- TUint32 iPageSizeLog2; ///< Log2 (cache page size)
+
+ TUint32 iPageSizeLog2; ///< Log2(cache page size or read granularity unit)
+ TUint32 iWrGranularityLog2; ///< Log2(cache write granularity unit). Can't be > iPageSizeLog2. '0' has a special meaning - "don't use write granularity"
+
mutable TBool iAllPagesValid;///< ETrue if all cache pages have valid data
TInt64 iCacheBasePos; ///< Cache pages base position, used to align them at cluster size
RPointerArray<CWTCachePage> iPages; ///< array of pointers to the cache pages. Used for organising LRU list
+
TUint32 iCacheDisabled :1; ///< if not 0 the cache is disabled totally and all reads and writes go via TDriveInterface directly
};
--- a/userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -39,11 +39,11 @@
@param aStartRamAddr the start address in the ram that this page content lives
*/
TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr)
-:iStartMedPos(aStartMedPos),
-iStartRamAddr(aStartRamAddr),
-iOwnerCache(aOwnerCache),
-iValid(EFalse),
-iLocked(EFalse)
+ :iStartMedPos(aStartMedPos),
+ iStartRamAddr(aStartRamAddr),
+ iOwnerCache(aOwnerCache),
+ iValid(EFalse),
+ iLocked(EFalse)
{
//__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes());
iType = EUnknown;
@@ -104,20 +104,22 @@
@param aDrive local drive interface to read/write media
@param aMinPageNum the minimum page number for the cache, includes iActive page and locked pages.
@param aMaxPageNum the maximum page number for the cache, includes iActive page, locked pages and unlocked pages.
-@param aPageSizeInBytesLog2 the log2 value of page size in bytes, assumes page size is always a power of two
+ @param aPageSizeInBytesLog2 Log2 of the page size in bytes, this is the cache read granularity
+ @param aWrGranularityLog2 Log2(cache write granularity)
*/
-CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2)
-:iPageSizeLog2(aPageSizeInBytesLog2),
-iMinSizeInPages(aMinPageNum),
-iMaxSizeInPages(aMaxPageNum),
-iDrive(aDrive),
-iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
-iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
-iLockedQCount(0),
-iUnlockedQCount(0),
-iHashFunction(HashFunction),
-iIdentityFunction(IdentityFunction),
-iLookupTable(iHashFunction, iIdentityFunction)
+CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2, TUint32 aWrGranularityLog2)
+ :iPageSizeLog2(aPageSizeInBytesLog2),
+ iWrGranularityLog2(aWrGranularityLog2),
+ iMinSizeInPages(aMinPageNum),
+ iMaxSizeInPages(aMaxPageNum),
+ iDrive(aDrive),
+ iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
+ iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
+ iLockedQCount(0),
+ iUnlockedQCount(0),
+ iHashFunction(HashFunction),
+ iIdentityFunction(IdentityFunction),
+ iLookupTable(iHashFunction, iIdentityFunction)
{
iPageSizeInBytes = 1 << aPageSizeInBytesLog2;
iCacheDisabled = EFalse;
@@ -174,10 +176,10 @@
/**
Static factory function of CDynamicDirCache
*/
-CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName)
+CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2, const TDesC& aClientName)
{
__PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2);
- CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2);
+ CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2, aWrGranularityLog2);
CleanupStack::PushL(pSelf);
pSelf->ConstructL(aClientName);
CleanupStack::Pop();
@@ -338,7 +340,7 @@
@param aDataLen the length of the content to be written.
@pre aDataLen should be no more than page size.
*/
-void CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
+TDynamicDirCachePage* CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
{
ASSERT(aDataLen <= iPageSizeInBytes);
//-- the data section is in the cache page entirely, take data directly from the cache
@@ -378,7 +380,8 @@
// always make writting events MRU
DoMakePageMRU(aPos);
- return;
+
+ return pPage;
}
/**
@@ -407,11 +410,37 @@
// __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd);
if(dataLen <= bytesToPageEnd)
- {
- WriteDataOntoSinglePageL(aPos, pData, dataLen);
+ {//-- make small write a multiple of a write granularity size (if it is used at all)
+ //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
+
+ TDynamicDirCachePage* pPage = WriteDataOntoSinglePageL(aPos, pData, dataLen);
+ TPtrC8 desBlock(aDes);
+
+ if(iWrGranularityLog2)
+ {//-- write granularity is used
+ const TInt64 newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the granularity unit size
+ TUint32 newLen = (TUint32)(aPos - newPos)+dataLen;
+ newLen = RoundUp(newLen, iWrGranularityLog2);
+
+ const TUint8* pd = pPage->PtrInPage(newPos);
+ desBlock.Set(pd, newLen);
+ aPos = newPos;
+
+ }
+
+ //-- write data to the media
+ const TInt nErr = iDrive.WriteCritical(aPos, desBlock);
+ if(nErr != KErrNone)
+ {//-- some serious problem occured during writing, invalidate cache.
+ InvalidateCache();
+ User::Leave(nErr);
+ }
+
+
}
else
- {
+ {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
+ //-- this is a very rare case.
__PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!"));
//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
@@ -439,8 +468,6 @@
{
WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
}
- }// else(dataLen <= bytesToPageEnd)
-
//-- write data to the media
const TInt nErr = iDrive.WriteCritical(aPos,aDes);
@@ -449,6 +476,11 @@
InvalidateCache();
User::Leave(nErr);
}
+
+
+ }// else(dataLen <= bytesToPageEnd)
+
+
}
/**
@@ -518,7 +550,7 @@
Implementation of pure virtual function.
@see MWTCacheInterface::PosCached()
*/
-TUint32 CDynamicDirCache::PosCached(const TInt64& aPos, TInt64& aCachedPosStart)
+TUint32 CDynamicDirCache::PosCached(TInt64 aPos)
{
const TInt64 pageStartMedPos = CalcPageStartPos(aPos);
@@ -535,7 +567,6 @@
// __PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos);
// have to unlock it before returning, otherwise there will be memory leak
UnlockPage(pPage);
- aCachedPosStart = pPage->StartPos();
return pPage->PageSizeInBytes();
}
else // if the unlocked page is not valid anymore, remove it
@@ -551,7 +582,6 @@
else if (pPage)
{
__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
- aCachedPosStart = pPage->StartPos();
return pPage->PageSizeInBytes();
}
--- a/userlibandfileserver/fileserver/sfat32/sl_dir_cache.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_dir_cache.h Sun Mar 14 13:15:32 2010 +0000
@@ -105,6 +105,7 @@
//---------------------------------------------------------------------------------------------------------------------------------
typedef TDblQue<TDynamicDirCachePage> TCachePageList;
+
/**
Dynamic directory cache.
For now it is directly derived from MWTCacheInterface.
@@ -114,7 +115,7 @@
{
public:
~CDynamicDirCache();
- static CDynamicDirCache* NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName);
+ static CDynamicDirCache* NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2, const TDesC& aClientName);
//-- overloads from the base class
void ReadL (TInt64 aPos, TInt aLength, TDes8& aDes);
@@ -122,7 +123,7 @@
void InvalidateCache(void);
void InvalidateCachePage(TUint64 aPos);
- TUint32 PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart);
+ TUint32 PosCached(TInt64 aPosToSearch);
TUint32 CacheSizeInBytes() const;
TInt Control(TUint32 aFunction, TUint32 aParam1, TAny* aParam2);
void SetCacheBasePos(TInt64 aBasePos);
@@ -136,11 +137,12 @@
void Info() const;
protected:
- CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinSizeInBytes, TUint32 aMaxSizeInBytes, TUint32 aPageSizeInBytesLog2);
+ CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinSizeInBytes, TUint32 aMaxSizeInBytes, TUint32 aPageSizeInBytesLog2, TUint32 aWrGranularityLog2);
void ConstructL(const TDesC& aClientName);
void ReadDataFromSinglePageL(TInt64 aPos, TInt aLength, TDes8& aDes);
- void WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen);
+ TDynamicDirCachePage* WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen);
+
TDynamicDirCachePage* FindPageByPos(TInt64 aPos);
TDynamicDirCachePage* UpdateActivePageL(TInt64 aPos);
TDynamicDirCachePage* AllocateAndLockNewPageL(TInt64 aStartMedPos);
@@ -162,7 +164,9 @@
void DoInvalidateCache(void);
private:
- TUint32 iPageSizeLog2; ///< log2 value of cache pages size in bytes
+ TUint32 iPageSizeLog2; ///< Log2(cache page size or read granularity unit)
+ TUint32 iWrGranularityLog2; ///< Log2(cache write granularity unit). Can't be > iPageSizeLog2. '0' has a special meaning - "don't use write granularity"
+
TUint32 iMinCacheSizeInBytes; ///< minimum cache data size
TUint32 iMaxCacheSizeInBytes; ///< maximum cache data size
TUint32 iMinSizeInPages; ///< minimum cache page number
--- a/userlibandfileserver/fileserver/sfat32/sl_disk.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_disk.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -126,7 +126,7 @@
const TUint32 KUidCachePageSzLog2 = 9; //-- 512 bytes in page
const TUint32 KUidCachePages = 64; //-- 64 pages; total cache size is 32K
- iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2);
+ iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2, 0);
//=========================== create directory cache
@@ -185,7 +185,7 @@
TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:");
clientName.Append('A'+iFatMount->DriveNumber());
- TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName));
+ TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, KDefSectorSzLog2, clientName));
if (err == KErrNone)
return;
@@ -197,7 +197,7 @@
//=========================== create legacy type of the directory cache
ASSERT(!ipDirCache);
- ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2);
+ ipDirCache = CMediaWTCache::NewL(iDrive, numPages, pageSzLog2, KDefSectorSzLog2);
__PRINT3(_L("CDirCache::NewL(drive: %C, NumPages=%d, PageSize=%u)"), 'A'+iFatMount->DriveNumber(), numPages, 1<<pageSzLog2);
}
--- a/userlibandfileserver/fileserver/sfat32/sl_drv.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_drv.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -43,12 +43,15 @@
}
/**
- pseudo-destructor.
+ Close the interface to the media driver
*/
void TDriveInterface::Close()
{
if(iMount)
+ {
iMount->LocalDrive()->SetMount(NULL);
+ }
+
iMount = NULL;
}
--- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1064,6 +1064,13 @@
const TBool newFileExists = (nRes == KErrNone); //-- ETrue if 'aNewName' file exists.
const TBool bNewNameIsVFAT = !IsLegalDosName(ptrNewName, EFalse, EFalse, EFalse, EFalse, ETrue);
+ if(!newFileExists)
+ {//-- invalidate directory iterators if aNewName doesn't exist
+ newName_VFatEntryPos.SetEndOfDir();
+ aNewName_DosEntryPos.SetEndOfDir();
+ }
+
+
if(renameMode && newFileExists)
{
if(!namesAreIdentical)
@@ -1143,7 +1150,7 @@
if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
{
- GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
+ GenerateShortNameL(aNewName_ParentDirPos.Cluster(), ptrNewName, shortName);
}
newDosEntry.SetName(shortName);
@@ -1971,8 +1978,6 @@
TFatDirEntry StartEntry1(aStartEntry);
TFatDirEntry DosEntry1(aDosEntry);
- TInt64 nCachedLinPos;
-
const TUint32 clSize = 1 << ClusterSizeLog2(); //-- media cluster size
const TUint32 cacheSz = pDirCache->CacheSizeInBytes(); //-- cache size in bytes
const TUint32 maxDirEntries = cacheSz >> KSizeOfFatDirEntryLog2; //-- maximal number of dir entries that can be in the cache
@@ -2021,7 +2026,7 @@
TBool PassedPageBoundary = EFalse;
const TInt64 entryLinPos = MakeLinAddrL(DosEntryPos1); //-- linear media position of the cluster for this directory
- const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos, nCachedLinPos); //-- indicates if entryLinPos is cached
+ const TUint32 cachePageSz = pDirCache->PosCached(entryLinPos); //-- indicates if entryLinPos is cached
if(cachePageSz)
{//-- current page is in the directory cache
//__PRINT2(_L("#-!! CFatMountCB::DoRummageDirCacheL() Searching cl:%d, lin Pos:%X"),DosEntryPos1.iCluster,(TUint32)entryLinPos);
@@ -3961,18 +3966,14 @@
FOREVER
{
-#ifdef _DEBUG
- const TInt e= GetDirEntry(aDosEntryPos, aDosEntry, startEntry, dummyLongName);
- __PRINT1(_L("CFatMountCB::FindVolumeLabelFileL: GetDir %d"), e);
- User::LeaveIfError(e);
-#else
User::LeaveIfError(GetDirEntry(aDosEntryPos, aDosEntry, startEntry, dummyLongName));
-#endif
+
if(aDosEntry.IsEndOfDirectory())
{
__PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: end of dir"));
User::Leave(KErrNotFound);
}
+
if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))
{
if(aDosEntry.IsErased())
@@ -3981,28 +3982,31 @@
User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
}
}
+
if(!aDosEntry.IsCurrentDirectory() && !aDosEntry.IsParentDirectory() && !aDosEntry.IsErased() && !aDosEntry.IsGarbage())
{
if(aDosEntry.Attributes() & KEntryAttVolume)
{
aLabel = aDosEntry.Name();
-#ifdef _DEBUG
dummyLongName.Copy(aLabel);
__PRINT1(_L("-CFatMountCB::FindVolumeLabelFileL: found [%S]"), &dummyLongName);
-#endif
break;
}
}
+
MoveToNextEntryL(aDosEntryPos);
+
if(IsRootDir(aDosEntryPos) && (aDosEntryPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()))
{
- __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: passed end of root"));
+ __PRINT(_L("-CFatMountCB::FindVolumeLabelFileL: Not found"));
User::Leave(KErrNotFound); //Allows maximum number of entries in root directory
}
+
if(aDosEntryPos.iCluster && (aDosEntryPos.iPos <= previousPosition))
{
DoCheckFatForLoopsL(aDosEntryPos.iCluster, previousCluster, changePreviousCluster, count);
}
+
previousPosition=aDosEntryPos.iPos;
}
}
--- a/userlibandfileserver/fileserver/sfat32/sl_vfat.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_vfat.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -29,11 +29,14 @@
// use second half of ISO Latin 1 character set for extended chars
const TUint KExtendedCharStart=0x80;
const TUint KExtendedCharEnd=0xff;
+const TUint KMaxVFatEntries = 21; ///< Max possible number of entries in the VFAT entryset
-LOCAL_C TBool IsLegalChar(TChar aCharacter,TBool aAllowWildChars,TBool aUseExtendedChars=EFalse,TBool aInScanDrive=EFalse)
-//
-// Returns ETrue if aCharacter is legal inside a dos filename
-//
+
+//-----------------------------------------------------------------------------
+/**
+ Returns ETrue if aCharacter is legal inside a dos filename
+*/
+static TBool IsLegalChar(TChar aCharacter,TBool aAllowWildChars,TBool aUseExtendedChars=EFalse,TBool aInScanDrive=EFalse)
{
if ((aCharacter==KMatchOne) || (aCharacter==KMatchAny))
return(aAllowWildChars);
@@ -46,7 +49,8 @@
return LocaleUtils::IsLegalShortNameCharacter(aCharacter,aUseExtendedChars);
}
-LOCAL_C void ReplaceFirstCharacterIfClashesWithE5L(TDes8& aShortName)
+//-----------------------------------------------------------------------------
+static void ReplaceFirstCharacterIfClashesWithE5L(TDes8& aShortName)
{
if (0 < aShortName.Length() && aShortName[0] == KEntryErasedMarker)
{
@@ -54,7 +58,8 @@
}
}
-LOCAL_C void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
+//-----------------------------------------------------------------------------
+static void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
{
TBool alreadyFoundExtensionDelimiter=EFalse;
@@ -130,10 +135,11 @@
}
}
+//-----------------------------------------------------------------------------
+/**
+ Create a legal shortname from aLongName
+*/
TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively)
-//
-// Create a legal shortname from aLongName
-//
{
TFileName longName(aLongName);
@@ -259,7 +265,7 @@
return shortName;
}
-
+//-----------------------------------------------------------------------------
/**
Check whether a Dos name is legal or not.
@@ -271,7 +277,6 @@
@return ETrue if the name is a legal DOS one.
*/
-
static TBool DoCheckLegalDosName(const TDesC& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
{
const TInt count=aName.Length();
@@ -388,6 +393,7 @@
return ETrue;
}
+//-----------------------------------------------------------------------------
/**
Check whether a Dos name is legal or not. Unicode version
parameters and return value absolutely the same as in DoCheckLegalDosName()
@@ -395,18 +401,19 @@
TBool IsLegalDosName(const TDesC16& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
{
- __PRINT(_L("IsLegalDosName 16"));
+ //__PRINT(_L("IsLegalDosName 16"));
return DoCheckLegalDosName(aName, anAllowWildCards, aUseExtendedChars, aInScanDrive, aAllowLowerCase, aIsForFileCreation);
}
+//-----------------------------------------------------------------------------
+/**
+ Returns ETrue and the entryPos of aName if found or EFalse
+*/
TBool CFatMountCB::FindShortNameL(const TShortName& aName,TEntryPos& anEntryPos)
-//
-// Returns ETrue and the entryPos of aName if found or EFalse
-//
{
- __PRINT(_L("VFAT::CFatMountCB::FindShortNameL"));
+ __PRINT(_L("CFatMountCB::FindShortNameL"));
TFatDirEntry fatEntry;
TInt count=0;
FOREVER
@@ -428,27 +435,29 @@
return EFalse;
}
+//-----------------------------------------------------------------------------
+/**
+ Returns ETrue if aName is unique, EFalse if a matching name is found.
+*/
TBool CFatMountCB::IsUniqueNameL(const TShortName& aName,TInt aDirCluster)
-//
-// Returns ETrue if aName is unique, EFalse if a matching name is found.
-//
{
- __PRINT(_L("VFAT::CFatMountCB::IsUniqueNameL"));
+ __PRINT(_L("CFatMountCB::IsUniqueNameL"));
TEntryPos entryPos(aDirCluster,0);
if (FindShortNameL(aName,entryPos))
return(EFalse);
return(ETrue);
}
+//-----------------------------------------------------------------------------
+/**
+ A legal dos name has been typed that clashes with a computer generated shortname
+ Change the shortname to something else.
+*/
void CFatMountCB::ReplaceClashingNameL(const TShortName& aNewName,const TEntryPos& anEntryPos)
-//
-// A legal dos name has been typed that clashes with a computer generated shortname
-// Change the shortname to something else.
-//
{
- __PRINT(_L("VFAT::CFatMountCB::ReplaceClashingNameL"));
+ __PRINT(_L("CFatMountCB::ReplaceClashingNameL"));
TFatDirEntry entry;
ReadDirEntryL(anEntryPos,entry);
__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
@@ -469,14 +478,22 @@
}
}
+//-----------------------------------------------------------------------------
+/**
+ Generate a legal dos filename as an alias for aName.
+ @return ETrue if aName is a legal dos name.
+*/
TBool CFatMountCB::GenerateShortNameL(TInt aDirCluster,const TDesC& aName,TShortName& aGeneratedName, TBool aForceRandomize)
-//
-// Generate a legal dos filename as an alias for aName.
-// Returns ETrue if aName is a legal dos name.
-//
{
- __PRINT(_L("VFAT::CFatMountCB::GenerateShortNameL"));
+ __PRINT1(_L("CFatMountCB::GenerateShortNameL() cl:%d"), aDirCluster);
+
+ if(!ClusterNumberValid(aDirCluster))
+ {
+ ASSERT(0);
+ User::Leave(KErrCorrupt);
+ }
+
// Given the long file-name "ABCDEFGHI.TXT", EPOC used to generate short
// file-names in the following pecking order:
// "ABCDEFGH.TXT",
@@ -546,142 +563,307 @@
}
-void TFatDirEntry::InitializeAsVFat(TUint8 aCheckSum)
-//
-// Initialize a FAT entry as a VFAT filename
-//
+
+//-----------------------------------------------------------------------------
+/**
+ Write up to KMaxVFatEntryName unicode chars from aName to the entry
+ @param aName long file name part that will be converted into the VFAT entryset
+ @param aLen length of the remaining name
+ @param aCheckSum DOS entry name checksum.
+*/
+void TFatDirEntry::SetVFatEntry(const TDesC& aName, TUint aLen, TUint8 aCheckSum)
{
-
- Mem::Fill(this,sizeof(SFatDirEntry),0xFF);
+ //-- initialise some VFAT entry specific fields
iData[0x0B]=0x0F;
iData[0x0C]=0x00; iData[0x0D]=aCheckSum;
iData[0x1A]=0x00; iData[0x1B]=0x00;
- }
-
-void TFatDirEntry::SetVFatEntry(const TDesC& aName,TInt aLen)
-//
-// Write up to KMaxVFatEntryName unicode chars from aName to the entry
-//
- {
TInt rem=aName.Length()-aLen;
TPtrC section(aName.Ptr()+aLen,Min(rem,KMaxVFatEntryName));
TBuf16<KMaxVFatEntryName> buf16;
buf16.Copy(section);
+
if (rem<KMaxVFatEntryName)
{
rem++;
buf16.ZeroTerminate();
buf16.SetLength(rem); // Zero termination doesn't increase the buf length
}
+
TUint8 orderNo=(TUint8)(aLen/KMaxVFatEntryName+1);
TInt s=Min(rem,5);
Mem::Copy(&iData[0x01],buf16.Ptr(),s*2);//Copy up to 10 bytes of buf16 into iData
+
TInt offset=s;
rem-=s;
s=Min(rem,6);
Mem::Copy(&iData[0x0E],buf16.Ptr()+offset,s*2);
+
offset+=s;
rem-=s;
+
s=Min(rem,2);
Mem::Copy(&iData[0x1C],buf16.Ptr()+offset,s*2);
rem-=s;
+
if (rem==0)
orderNo|=0x40;
+
iData[0]=orderNo;
}
+
+//-----------------------------------------------------------------------------
+/**
+ Read KMaxVFatEntryName unicode chars from the entry
+*/
void TFatDirEntry::ReadVFatEntry(TDes16& aBuf) const
-//
-// Read KMaxVFatEntryName unicode chars from the entry
-//
{
-
aBuf.SetLength(KMaxVFatEntryName);
Mem::Copy(&aBuf[0],&iData[0x01],5*2);
Mem::Copy(&aBuf[5],&iData[0x0E],6*2);
Mem::Copy(&aBuf[11],&iData[0x1C],2*2);
}
-void CFatMountCB::WriteDirEntryL(TEntryPos& aPos,const TFatDirEntry& aFatDirEntry,const TDesC& aLongName)
-//
-// Write a VFAT directory entry to disk at position aPos - leave aPos refering to the dos entry
-// Assumes sufficient space has been created for it by AddDirEntry.
-//
- {
+//-----------------------------------------------------------------------------
+/**
+ Write a VFAT directory entry set to disk at position aPos - leave aPos refering to the dos entry
+ Assumes sufficient space has been created for it by AddDirEntry.
+ For Rugged FAT mode bulk writing of the whole entryset is OK. If the entryset fits into media atomic write unit, the
+ write is transactional anyway. if the entryset is split between media atomic write units, the part of it with the DOS
+ entry is written last; if this write operation fails, the artifact would be just several orphaned VFAT entries;
- __PRINT(_L("VFAT::CFatMountCB::WriteDirEntryL"));
+ @param aPos in: specifies the entryste start position. out: points to the last (DOS) entry in the created entryset
+ @param aFatDirEntry aDosEntry DOS entry
+ @param aLongName VFAT entry long name
+*/
+void CFatMountCB::WriteDirEntryL(TEntryPos& aPos, const TFatDirEntry& aDosEntry, const TDesC& aLongName)
+ {
+ __PRINT2(_L("CFatMountCB::WriteDirEntryL() cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
__ASSERT_DEBUG(aLongName.Length(),Fault(EVFatNoLongName));
- TEntryPos startPos(aPos.iCluster,aPos.iPos);
- TUint8 localBuf[KDefaultSectorSize];
- TUint8 cksum=CalculateShortNameCheckSum(aFatDirEntry.Name());
- TInt numEntries=NumberOfVFatEntries(aLongName.Length())-1; // Excluding dos entry
- // see if all entries written to one sector
- // single sector writes not supported if sector size>default size
- TInt dosOffset=numEntries<<KSizeOfFatDirEntryLog2;
- TInt absolutePos=(aPos.iCluster<<ClusterSizeLog2())+ClusterRelativePos(aPos.iPos);
- TBool isSameSector=(((absolutePos^(absolutePos+dosOffset))>>SectorSizeLog2())==0 && ((TUint)(1<<SectorSizeLog2())<=KDefaultSectorSize));
- TFatDirEntry vFatEntry;
- vFatEntry.InitializeAsVFat(cksum);
- TInt offset=0;
+
+ //-- scratch buffer for whole VFAT entryset. Max number of entries in it is 21 entry or 672 bytes.
+ //-- in the worst case the entryset can span across 3 clusters (512 bytes per cluster)
+ //-- Using the scratch buffer is not ideal, but write-back directory cache isn't in place yet
+ const TUint KBufSize = 680;
+ TUint8 scratchBuf[KBufSize];
+
+ const TUint8 cksum=CalculateShortNameCheckSum(aDosEntry.Name());
+ TUint numEntries=NumberOfVFatEntries(aLongName.Length())-1; // Excluding dos entry
+
+ ASSERT(KBufSize >= ((numEntries+1)<<KSizeOfFatDirEntryLog2));
+ TEntryPos startPos;
+
+ for(;;)
+ {
+ TInt posInBuf = 0;
+ startPos = aPos;
+ TBool movedCluster = EFalse;
+
+ while(numEntries)
+ {
+ TFatDirEntry* pEntry = (TFatDirEntry*)(&scratchBuf[posInBuf]);
+ pEntry->SetVFatEntry(aLongName, KMaxVFatEntryName*(numEntries-1), cksum); //KMaxVFatEntryName=13
+
+ posInBuf += KSizeOfFatDirEntry;
+ MoveToNextEntryL(aPos);
+
+ numEntries--;
+ movedCluster = (startPos.Cluster() != aPos.Cluster()); //-- if moved to another cluser, need to flush buffer
+
+ if(!numEntries || movedCluster)
+ break; //-- VFAT entryset is completed
+ }
+
+ if(movedCluster)
+ {
+ DirWriteL(startPos, TPtrC8(&scratchBuf[0], posInBuf));
+ continue;
+ }
+
+ if(!numEntries)
+ {//-- need to append DOS entry
+ Mem::Copy(&scratchBuf[posInBuf], &aDosEntry, KSizeOfFatDirEntry);
+ posInBuf+= KSizeOfFatDirEntry;
+ DirWriteL(startPos, TPtrC8(&scratchBuf[0], posInBuf));
+ break;
+ }
+
+ }//for(;;)
+ }
+
+
+
+//---------------------------------------------------------------------------------
+
+void CFatMountCB::DoEraseEntrySetChunkL(const TEntrySetChunkInfo& aEntrySetChunk)
+ {
+
+ //-- scratch buffer for whole VFAT entryset. Max number of entries in it is 21 entry or 672 bytes.
+ //-- in the worst case the entryset can span across 3 clusters (512 bytes per cluster)
+ //-- Using the scratch buffer is not ideal, but write-back directory cache isn't in place yet
+
+ const TUint KBufSize = 680;
+ TBuf8<KBufSize> scratchBuf;
+
+ TUint numEntries = aEntrySetChunk.iNumEntries;
+
+ ASSERT(numEntries >0 && numEntries <= KMaxVFatEntries);
+ const TUint32 KChunkLen = numEntries << KSizeOfFatDirEntryLog2;
+
+ DirReadL(aEntrySetChunk.iEntryPos, KChunkLen, scratchBuf);
+
+ TInt posInBuf = 0;
while (numEntries--)
{
- vFatEntry.SetVFatEntry(aLongName,KMaxVFatEntryName*numEntries);// KMaxVFatEntryName=13
- if(isSameSector)
- {
- Mem::Copy(&localBuf[offset],&vFatEntry,KSizeOfFatDirEntry);
- offset+=KSizeOfFatDirEntry;
- MoveToNextEntryL(aPos);
- }
- else
- {
- WriteDirEntryL(aPos,vFatEntry);
- MoveToNextEntryL(aPos);
- }
- }
- if(isSameSector)
- {
- Mem::Copy(&localBuf[offset],&aFatDirEntry,KSizeOfFatDirEntry);
-
- //-- use special interface to access FAT directory file
- DirWriteL(startPos,TPtrC8(&localBuf[0],dosOffset+KSizeOfFatDirEntry));
+ TFatDirEntry* pEntry = (TFatDirEntry*)(scratchBuf.Ptr()+posInBuf);
+ pEntry->SetErased();
+ posInBuf += KSizeOfFatDirEntry;
}
- else
- WriteDirEntryL(aPos,aFatDirEntry);
- }
+
+ DirWriteL(aEntrySetChunk.iEntryPos, scratchBuf);
+ }
+//---------------------------------------------------------------------------------
+/**
+ Erase whole VFAT entryset.
+ For Rugged FAT the situation is more complicated: we need firstly delete the DOS entry _atomically_ i.e. if this operation fails,
+ the whole VFAT entryset won't be broken. Deleting VFAT entries doesn't require the atomic media writes; DOS entry contains necessary
+ information about data stream.
+
+ @param aPos position of the entryset start in the directory.
+ @param aFirstEntry first entry in the entryset, it can be DOS entry
+
+*/
void CFatMountCB::EraseDirEntryL(TEntryPos aPos,const TFatDirEntry& aFirstEntry)
-//
-// Mark all entries in a VFat directory entry as erased
-//
{
- __PRINT(_L("VFAT::CFatMountCB::EraseDirEntryL"));
- TInt numEntries=0;
+ __PRINT2(_L("CFatMountCB::EraseDirEntryL() cl:%d, offset:%d"), aPos.Cluster(), aPos.Pos());
+
+ TUint numEntries=0;
if (aFirstEntry.IsVFatEntry())
+ {
numEntries=aFirstEntry.NumFollowing();
- if(IsRuggedFSys()&&numEntries)
- {
- TInt count=numEntries;
- TEntryPos pos=aPos;
- while(count--)
- MoveToNextEntryL(pos);
- EraseDirEntryL(pos);
- numEntries--;
+ numEntries++; //-- take into account the last DOS entry
}
- FOREVER
- {
+ else
+ {//-- we are deleting a single DOS entry. This is an atomic operation.
EraseDirEntryL(aPos);
- if (!numEntries--)
- break;
- MoveToNextEntryL(aPos);
- }
- }
+ return;
+ }
+
+ ASSERT(numEntries > 1 && numEntries <= KMaxVFatEntries);
+
+ TEntrySetChunkInfo chunksInfo[TEntrySetChunkInfo::KMaxChunks];
+
+ //-- 1. check if the entryset fits into a unit of write ganularity. This will be 1 sector for rugged FAT or 1 cluster otherwise
+
+ TUint32 MaxWriteGranularityLog2;
+
+ if(IsRuggedFSys())
+ {
+ MaxWriteGranularityLog2 = AtomicWriteGranularityLog2();
+ }
+ else if(IsRootDir(aPos))
+ {//-- root dir. for FAT12/16 is a special case, it is not made of clusters. it's unit is 1 sector.
+ MaxWriteGranularityLog2 = KDefSectorSzLog2;
+ }
+ else
+ {//-- minimal unit size will be a cluster
+ MaxWriteGranularityLog2 = ClusterSizeLog2();
+ }
+
+
+ {
+ const TUint64 KEntrySetStartPos = MakeLinAddrL(aPos);
+ const TUint64 KEntrySetLogicalEndPos = KEntrySetStartPos + (numEntries << KSizeOfFatDirEntryLog2);
+
+ const TUint64 KBlockEndPos = ((KEntrySetLogicalEndPos-1) >> MaxWriteGranularityLog2) << MaxWriteGranularityLog2;
+ const TUint64 KBlockStartPos = (KEntrySetStartPos >> MaxWriteGranularityLog2) << MaxWriteGranularityLog2;
+
+ if(KBlockEndPos == KBlockStartPos)
+ {//-- whole entryet is in the same block; the whole entryset erase operation will be atomic for Rugged/non-rugged FAT
+ chunksInfo[0].iEntryPos = aPos;
+ chunksInfo[0].iNumEntries = numEntries;
+ DoEraseEntrySetChunkL(chunksInfo[0]);
+ return;
+ }
+
+ }
+
+ //-- the entryset is split on max. 3 parts between units of write granularity (see MaxWriteGranularityLog2).
+ ASSERT(numEntries > 1 && numEntries <= KMaxVFatEntries);
+
+ TInt cntChunk = 1; //-- there is at least 1 entries chunk
+ TEntrySetChunkInfo* pChunkInfo = chunksInfo;
+
+ //-- collect information about dir. entry chunks that reside in different units of write granularity
+ for(;;)
+ {
+ TBool movedUnit = EFalse;
+ pChunkInfo->iEntryPos = aPos;
+ pChunkInfo->iNumEntries = 0;
+
+ const TUint64 KChunkStartPos = MakeLinAddrL(aPos);
+ const TUint64 KChunkBlockStartPos = (KChunkStartPos >> MaxWriteGranularityLog2) << MaxWriteGranularityLog2;
+ const TUint64 KChunkBlockEndPos = (KChunkBlockStartPos-1) + (1<<MaxWriteGranularityLog2);
+ while(numEntries)
+ {
+ pChunkInfo->iNumEntries++;
+ MoveToNextEntryL(aPos);
+
+ numEntries--;
+ const TUint64 currPos = MakeLinAddrL(aPos);
+ movedUnit = !(currPos >= KChunkBlockStartPos && currPos <= KChunkBlockEndPos);
+
+ if(!numEntries || movedUnit)
+ {
+ break;
+ }
+
+ }
+
+ if(movedUnit && numEntries)
+ {//-- move to the next unit of write granularity
+ ++pChunkInfo;
+ ++cntChunk;
+ ASSERT(cntChunk <= TEntrySetChunkInfo::KMaxChunks);
+ continue;
+ }
+
+
+ ASSERT(!numEntries);
+ break;
+ }
+
+ //-- now do bulk deletion, write data based on collected entries chunks.
+ ASSERT(cntChunk > 0);
+
+ //-- if it is a rugged FAT, we need to delete DOS entry first; it will be in the last chunk.
+ if(IsRuggedFSys())
+ {
+ const TInt dosEntryChunk = cntChunk-1;
+ DoEraseEntrySetChunkL(chunksInfo[dosEntryChunk]);
+ cntChunk--;
+ }
+
+ //-- it is also possible to joint entryset chunks together here if they belong to the same cluster.
+ //-- the atomic write here is not required.
+
+ //-- erase the rest of entries in reamining chunks.
+ for(TInt i=0; i<cntChunk; ++i)
+ {
+ DoEraseEntrySetChunkL(chunksInfo[i]);
+ }
+
+}
+
+//---------------------------------------------------------------------------------
+/**
+ Convert the volume label using the algorithm specified in the current locale-DLL.
+*/
void LocaleUtils::ConvertFromUnicodeL(TDes8& aForeign, const TDesC16& aUnicode, TFatUtilityFunctions::TOverflowAction aOverflowAction)
-//
-// Convert the volume label using the algorithm specified in the current locale-DLL.
-//
{
if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
{
@@ -692,11 +874,11 @@
GetCodePage().ConvertFromUnicodeL(aForeign, aUnicode, TCodePageUtils::EOverflowActionTruncate);
}
}
-
+//---------------------------------------------------------------------------------
+/**
+ Convert the volume label using the algorithm specified in the current locale-DLL.
+*/
void LocaleUtils::ConvertToUnicodeL(TDes16& aUnicode, const TDesC8& aForeign, TFatUtilityFunctions::TOverflowAction aOverflowAction)
-//
-// Convert the volume label using the algorithm specified in the current locale-DLL.
-//
{
if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
{
@@ -708,10 +890,20 @@
}
}
+//---------------------------------------------------------------------------------
+/**
+ Convert the volume label using the algorithm specified in the current locale-DLL.
+*/
TBool LocaleUtils::IsLegalShortNameCharacter(TUint aCharacter,TBool aUseExtendedChars)
-//
-// Convert the volume label using the algorithm specified in the current locale-DLL.
-//
{
return GetCodePage().IsLegalShortNameCharacter(aCharacter, aUseExtendedChars);
}
+
+
+
+
+
+
+
+
+
--- a/userlibandfileserver/fileserver/sfile/sf_dat.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_dat.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -72,6 +72,8 @@
TCorruptLogRec* gCorruptLogRecordList=NULL;
TInt gNumberOfCorruptHits=0;
HBufC* gCorruptFileNamesListFile=NULL;
+TInt SessionCount; // number of CSessionFs's
+TInt ObjectCount; // number of CFsObjects
#endif
--- a/userlibandfileserver/fileserver/sfile/sf_debug.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_debug.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -579,6 +579,19 @@
EnableFatUtilityFunctions = ETrue;
return KErrNone;
}
+ case KControlIoSessionCount:
+ {
+ TPckgBuf<TInt> pkgBuf(SessionCount);
+ TInt r=aRequest->Write(2,pkgBuf);
+ return r;
+ }
+ case KControlIoObjectCount:
+ {
+ TPckgBuf<TInt> pkgBuf(ObjectCount);
+ TInt r=aRequest->Write(2,pkgBuf);
+ return r;
+ }
+
}
#endif
--- a/userlibandfileserver/fileserver/sfile/sf_memory_client.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_memory_client.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -34,11 +34,7 @@
{
const TUint32 segCnt = iTouchedRegionFlag <= iReservedRegionMarkInSegs ?
iReservedRegionMarkInSegs : iTouchedRegionFlag;
- TInt r = DecommitSegments(iBase, segCnt);
- if (r != KErrNone) // this 'if() {}' is to remove build warnings
- {
- ASSERT(0);
- }
+ DecommitSegments(iBase, segCnt);
iReusablePagePool.Close();
delete iName;
}
@@ -95,7 +91,6 @@
iBase = iManager.Base() + aOffsetInBytes;
iReservedRegionMarkInSegs = iMinSizeInSegs;
TInt r = iManager.AllocateAndLockSegments(iBase, iReservedRegionMarkInSegs);
- ASSERT(r==KErrNone);
User::LeaveIfError(r);
iTouchedRegionFlag = 0;
__PRINT(_L("CCacheMemoryClient::ConstructL() return 0"));
--- a/userlibandfileserver/fileserver/sfile/sf_memory_man.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_memory_man.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -125,10 +125,9 @@
// if it is a new drive/file system who wants to connect, create a new client for it
// parameter validation
- ASSERT(iSizeInBytes > iCurrentOffsetMark + (aMaxSizeInSegs << SegmentSizeInBytesLog2()));
if (iSizeInBytes < iCurrentOffsetMark + (aMaxSizeInSegs << SegmentSizeInBytesLog2()))
{
- ASSERT(0);
+ __PRINT1(_L("CCacheMemoryManager::ConnectClientL([%S]) failed, please check \"GlobalCacheMemorySize\" setting!!!"), &aClientName);
User::Leave(KErrArgument);
}
@@ -140,7 +139,6 @@
TInt err = iRegisteredClients.Append(client);
if (err != KErrNone)
{
- ASSERT(0);
delete client;
client = NULL;
User::Leave(err);
@@ -289,7 +287,10 @@
*/
void CCacheMemoryManagerFactory::CreateL()
{
- iCacheMemoryManager = CCacheMemoryManager::NewL(TGlobalCacheMemorySettings::CacheSize());
+ if (TGlobalCacheMemorySettings::CacheSize() > 0)
+ iCacheMemoryManager = CCacheMemoryManager::NewL(TGlobalCacheMemorySettings::CacheSize());
+ else
+ __PRINT(_L("\"GlobalCacheMemorySize\" set <= 0, CCacheMemoryManager is not created!!!"));
}
/**
--- a/userlibandfileserver/fileserver/sfile/sf_notify.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_notify.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -333,6 +333,18 @@
return(isFound);
}
+CNotifyInfo* TBaseQue::DoFindEntry(CSessionFs* aSession, TRequestStatus* aStatus)
+ {
+ TDblQueIter<CNotifyInfo> q(iHeader);
+ CNotifyInfo* info;
+ while((info=q++)!=NULL)
+ {
+ if(info->Session()==aSession && (!aStatus || aStatus==info->Status()))
+ return info;
+ }
+ return NULL;
+ }
+
void TBaseQue::DoCancelAll(TInt aCompletionCode)
//
// Cancel all notifications
@@ -654,13 +666,20 @@
TInt TDismountNotifyQue::CancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus)
//
-//
+// Returns the drive number or KErrNotFound
//
{
iQLock.Wait();
- TBool isFound=TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
+
+ // return the drive number
+ CDismountNotifyInfo* info = (CDismountNotifyInfo*) DoFindEntry(aSession, aStatus);
+ TInt driveNumber = info ? info->DriveNumber() : KErrNotFound;
+
+ TBaseQue::DoCancelSession(aSession,aCompletionCode,aStatus);
+
iQLock.Signal();
- return(isFound);
+
+ return(driveNumber);
}
void TDismountNotifyQue::CancelAll(TInt aCompletionCode)
@@ -929,14 +948,15 @@
iDebugQue.CancelSession(aSession,KErrCancel,aStatus);
}
-void FsNotify::CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus)
+TInt FsNotify::CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus)
//
// Cancel all media removal notification(s) setup by aSession (if aStatus == NULL)
-// else cancels all oustanding notifications(s) for the session
+// else cancels all outstanding notifications(s) for the session
//
{
__PRINT2(_L("FsNotify::CancelDismountNotifySession() aSession=0x%x aStatus=0x%x"),aSession,aStatus);
- iDismountNotifyQue.CancelSession(aSession,KErrCancel,aStatus);
+ TInt drive = iDismountNotifyQue.CancelSession(aSession,KErrCancel,aStatus);
+ return drive;
}
void FsNotify::CancelSession(CSessionFs* aSession)
--- a/userlibandfileserver/fileserver/sfile/sf_obj.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_obj.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -156,7 +156,9 @@
*/
EXPORT_C CFsObject::CFsObject()
{
-
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ __e32_atomic_add_ord32(&ObjectCount, 1);
+#endif
// iContainer=NULL;
// iName=NULL;
iAccessCount=1;
@@ -179,6 +181,9 @@
__ASSERT_ALWAYS(!iContainer,Fault(EObjDestructorContainer));
if(iName)
User::Free(iName);
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ __e32_atomic_add_ord32(&ObjectCount, (TUint32) -1);
+#endif
}
--- a/userlibandfileserver/fileserver/sfile/sf_ses.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_ses.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -27,6 +27,9 @@
iReservedDriveAccess(KReservedDriveAccessArrayGranularity, _FOFF(TReservedDriveAccess, iDriveNumber)),
iId(0)
{
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ __e32_atomic_add_ord32(&SessionCount, 1);
+#endif
}
CSessionFs *CSessionFs::NewL()
@@ -64,6 +67,10 @@
iSessionFlagsLock.Close();
if(iDisconnectRequest)
delete(iDisconnectRequest);
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ __e32_atomic_add_ord32(&SessionCount, (TUint32) -1);
+#endif
}
void CSessionFs::CreateL()
--- a/userlibandfileserver/fileserver/sfile/sf_std.h Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_std.h Sun Mar 14 13:15:32 2010 +0000
@@ -1511,6 +1511,7 @@
~CDismountNotifyInfo();
void Initialise(TNotifyDismountMode aMode, TInt aDriveNumber,TRequestStatus* iStatus,const RMessagePtr2& aMessage,CSessionFs* aSession);
TBool IsMatching(TNotifyDismountMode aMode, TInt aDriveNumber, CSessionFs* aSession);
+ inline TInt DriveNumber() {return iDriveNumber;}
private:
TNotifyDismountMode iMode;
TInt iDriveNumber;
@@ -1527,6 +1528,7 @@
void DoAddNotify(CNotifyInfo* aInfo);
TBool DoCancelSession(CSessionFs* aSession,TInt aCompletionCode,TRequestStatus* aStatus=NULL);
void DoCancelAll(TInt aCompletionCode);
+ CNotifyInfo* DoFindEntry(CSessionFs* aSession, TRequestStatus* aStatus=NULL);
TBool IsEmpty();
protected:
TDblQue<CNotifyInfo> iHeader;
@@ -1597,7 +1599,7 @@
static void CancelChangeSession(CSessionFs* aSession,TRequestStatus* aStatus=NULL);
static void CancelDiskSpaceSession(CSessionFs* aSession,TRequestStatus* aStatus=NULL);
static void CancelDebugSession(CSessionFs* aSession, TRequestStatus* aStatus=NULL);
- static void CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus=NULL);
+ static TInt CancelDismountNotifySession(CSessionFs* aSession, TRequestStatus* aStatus=NULL);
static void CancelSession(CSessionFs* aSession);
static TBool HandlePendingDismount(CSessionFs* aSession, TInt aDriveNumber);
static TBool IsChangeQueEmpty(TInt aDrive);
@@ -1803,6 +1805,8 @@
extern TInt UserHeapAllocFailCount;
extern TInt KernHeapAllocFailCount;
extern TInt MessageCount;
+extern TInt SessionCount;
+extern TInt ObjectCount;
void PrintHeapSize(const TDesC& aMessage);
--- a/userlibandfileserver/fileserver/sfile/sf_sys.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_sys.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -1223,7 +1223,9 @@
//
{
CSessionFs* session = aRequest->Session();
- FsNotify::CancelDismountNotifySession(session, (TRequestStatus*)aRequest->Message().Ptr0());
+ TInt drive = FsNotify::CancelDismountNotifySession(session, (TRequestStatus*)aRequest->Message().Ptr0());
+ if (drive >= 0)
+ TheDrives[drive].SetDismountDeferred(EFalse);
return KErrNone;
}
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -353,13 +353,13 @@
if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
{
__HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]\n"))
- return KErrNotSupported;
+ return KErrUnknown;
}
if (info.iPeripheralDeviceType != 0)
{
__HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]\n"))
- return KErrNotSupported;
+ return KErrUnknown;
}
iRemovableMedia = info.iRemovable;
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiblockcmds.cpp Mon Mar 08 11:57:08 2010 +0000
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiblockcmds.cpp Sun Mar 14 13:15:32 2010 +0000
@@ -57,7 +57,7 @@
}
TInt modeDataLength = aPtr[0];
- if (aPtr.Length() - 1 < modeDataLength)
+ if (aPtr.Length() - 1 > modeDataLength)
{
User::Leave(KErrGeneral);
}
@@ -121,8 +121,8 @@
User::Leave(KErrGeneral);
}
- TInt modeDataLength = BigEndian::Get32(&aPtr[0]);
- if (aPtr.Length() - 2 < modeDataLength)
+ TInt modeDataLength = BigEndian::Get16(&aPtr[0]);
+ if (aPtr.Length() - 2 > modeDataLength)
{
User::Leave(KErrGeneral);
}